SQL Update command not working from c# code behind - c#

I know this question has been asked several times and I read those with no luck :( So I am asking it again with my code.
I have created a stored procedure to update a database table.
Stored procedure:
CREATE PROCEDURE usp_PettyCash_EditExpenseInfo
(
#ExpenseID bigint,
#ExpenseName varchar(100),
#SAPCode varchar(50),
#MaxLimit decimal,
#ExpenseType varchar(50)
)
AS
BEGIN
UPDATE t_ExpenseInfo
SET ExpenseName = #ExpenseName,
SAPCode = #SAPCode,
MaxLimit = #MaxLimit,
ExpenseType = #ExpenseType
WHERE
ExpenseID = #ExpenseID
END
GO
But when I call this from code behind with below code, it gives the exception similar to
Error in converting from nvarchar to bigint
Code behind:
oOleDbCommand.Parameters.AddWithValue("#ExpenseName", oInputExpense.ExpenseName.ToString());
oOleDbCommand.Parameters.AddWithValue("#SAPCode", oInputExpense.SAPCode.ToString());
oOleDbCommand.Parameters.AddWithValue("#MaxLimit", Convert.ToDecimal(oInputExpense.MaxLimit));
oOleDbCommand.Parameters.AddWithValue("#ExpenseType", oInputExpense.ExpenseType.ToString());
oOleDbCommand.Parameters.AddWithValue("#ExpenseID", Convert.ToDouble(oInputExpense.ExpenseID.ToString()));
I also tried this:
oOleDbCommand.CommandText = "UPDATE t_ExpenseInfo SET ExpenseName='" + oInputExpense.ExpenseName.ToString() + "', SAPCode='" + oInputExpense.SAPCode.ToString() + "', MaxLimit=" + oInputExpense.MaxLimit + ", ExpenseType='" + oInputExpense.ExpenseType.ToString() + "' WHERE ExpenseID=" + oInputExpense.ExpenseID + "";
this DIRECT command runs OK from SQL Query Analyzer from from code behind this also give an "Access Violation" error.
I am really confused about what to do? Please help !

is there any particular reason why you're using OleDbCommand instead of the "native" SQL Server SqlCommand ??
I would try this:
using(SqlConnection conn = new SqlConnection("(add your connection string here)"))
using(SqlCommand cmd = new SqlCommand("dbo.usp_PettyCash_EditExpenseInfo", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
// add parameters with defined type!
cmd.Parameters.Add("#ExpenseID", SqlDbType.BigInt).Value = .....;
cmd.Parameters.Add("#ExpenseName", SqlDbType.VarChar, 100).Value = ".....";
cmd.Parameters.Add("#SAPCode", SqlDbType.VarChar, 50).Value = ".....";
cmd.Parameters.Add("#MaxLimit", SqlDbType.Decimal, 15, 2).Value = 100.00;
cmd.Parameters.Add("#ExpenseType", SqlDbType.VarChar, 50).Value = "......";
// open connection, call stored procedure, close connection
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
Basically, I prefer using the native SqlConnection/SqlCommand over the old, legacy OleDb stuff, and I also prefer to explicitly specify what type my parameters are - don't rely on ADO.NET or some other part figuring it out automagically - when it has to guess, it can get it wrong, and error like the one you see might occur. If you define it yourself, you're in control!

Try Convert.ToInt64(...) instead of Convert.ToDouble(oInputExpense.ExpenseID.ToString())

I collect the query in SQL Profiler and find out that OleDB doesn't care about the name of parameter, but it cares about order of given parameters.
In your case ExpenseName is given as first parameter and it tried to convert it to ExpenseId (first parameter in your stored procedure).
Here is query from SQL Profiler:
exec usp_PettyCash_EditExpenseInfo N'ExpenseName',N'SAP',21.209999084472656,N'a',1
Try to change order of given parameters. I hope it help.

Currently I am using the 1st part. But I have checked both are working :)
OleDbCommand.Parameters.Add("#ExpenseID", OleDbType.BigInt).Value = Convert.ToInt64(oInputExpense.ExpenseID);
OleDbCommand.Parameters.Add("#ExpenseName", OleDbType.VarChar).Value = Convert.ToString(oInputExpense.ExpenseName);
OleDbCommand.Parameters.Add("#SAPCode", OleDbType.VarChar).Value = Convert.ToString(oInputExpense.SAPCode);
OleDbCommand.Parameters.Add("#MaxLimit", OleDbType.Decimal, 2).Value = Convert.ToDecimal(oInputExpense.MaxLimit);
OleDbCommand.Parameters.Add("#ExpenseType", OleDbType.VarChar).Value = Convert.ToString(oInputExpense.ExpenseType);
//OleDbCommand.Parameters.AddWithValue("#ExpenseID", Convert.ToInt64(oInputExpense.ExpenseID.ToString()));
//OleDbCommand.Parameters.AddWithValue("#ExpenseName", oInputExpense.ExpenseName.ToString());
//OleDbCommand.Parameters.AddWithValue("#SAPCode", oInputExpense.SAPCode.ToString());
//OleDbCommand.Parameters.AddWithValue("#MaxLimit", Convert.ToDecimal(oInputExpense.MaxLimit));
//OleDbCommand.Parameters.AddWithValue("#ExpenseType", oInputExpense.ExpenseType.ToString());

Related

Executing SqlCommand fails due to "string or binary data would be truncated. the statement has been terminated" error

I am trying to save changes made in a GridView of DevExpress into a table of my DataBase, and I was able to do it with the following code:
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings[2].ConnectionString))
{
con.Open();
GridView gv = sender as GridView;
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "UPDATE dbo.tb_Alumno set " + e.Column.FieldName + " = '" + e.Value + "' where pk_alumno = " + gv.GetRowCellValue(gv.FocusedRowHandle, gv.Columns[0]);
cmd.ExecuteNonQuery();
}
}
I have been having this problem since I added parametric command to prevent SQL injection. I have already hardcoded the values for each parameter to encounter the one that provides the error and is the #val parameter:
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings[2].ConnectionString))
{
con.Open();
GridView gv = sender as GridView;
using (SqlCommand cmd = con.CreateCommand())
{
#region Parameters
//cmd.CommandText = "UPDATE dbo.tb_Alumno set " + e.Column.FieldName + " = '" + e.Value + "' where pk_alumno = " + gv.GetRowCellValue(gv.FocusedRowHandle, gv.Columns[0]);
cmd.CommandText = "UPDATE dbo.tb_Alumno set #col = #val where pk_alumno = #id";
cmd.Parameters.AddWithValue("#col", e.Column.FieldName);
cmd.Parameters.AddWithValue("#val", e.Value);
//cmd.Parameters["#val"].SqlDbType = SqlDbType.VarChar;
cmd.Parameters.AddWithValue("#id", gv.GetRowCellValue(gv.FocusedRowHandle, gv.Columns[0]));
#endregion
try
{ cmd.ExecuteNonQuery(); }
catch (Exception xe)
{ MessageBox.Show(xe.Message); }
}
}
Aditional information that I can provide:
The error comes when executing the query
I am using a gridview from DevExpress15.1 in the 'CellValueChanged' event
Data type of the Database is varchar(50) and the parameter is nvarchar
The error comes when the string exceeds 6 characters (even being "hardcoded")
For example, if I use the following parameter it will throw the same error:
cmd.Parameters.AddWithValue("#col", "name");
cmd.Parameters.AddWithValue("#val", "More than 6 characters");
cmd.Parameters.AddWithValue("#id", 1);
This happens with all fields
If I change the middle line to the following I do not have problems at all
cmd.Parameters.AddWithValue("#val", "This<7");
I already tryed to match datatypes as you could see from the commented line, but that throws me no error and does not update the table. I have tested this on other columns too and have the same basic problem.
So my question is, ¿What piece of code should I use to prevent SQL inyection in this particular case?
Here's an example of using a stored procedure that uses dynamic sql. Notice the dynamic sql utilizes sp_executesql which helps prevent sql injection attacks.
The SQL code
create PROCEDURE [dbo].[SP_DynamicUpdate]
-- Add the parameters for the stored procedure here
#col varchar(50) = null,
#val varchar(50) = null,
#id int = 0
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
-- declaring strings
DECLARE #SQLString nvarchar(1024);
DECLARE #ParmDefinition nvarchar(512)
SET #SQLString =
N'Update
dbo.tb_Alumno
set
#col_Param = #val_Param
where
pk_alumno = #id_Param'
-- creating the parameters
SET #ParmDefinition = N'#col_Param varchar(50), ';
SET #ParmDefinition = #ParmDefinition + N'#val_Param varchar(50), ';
SET #ParmDefinition = #ParmDefinition + N'#id_Param int ';
-- Executing the stored procedure
EXECUTE sp_executesql #SQLString,
#ParmDefinition,
#col_Param = #col,
#val_Param = #val,
#id_Param = #id
END
the C# code
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings[2].ConnectionString))
{
GridView gv = sender as GridView;
using (SqlCommand cmd = new SqlCommand("dbo.SP_DynamicUpdate", con))
{
#region Parameters
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#col", e.Column.FieldName);
cmd.Parameters.AddWithValue("#val", e.Value);
cmd.Parameters.AddWithValue("#id", gv.GetRowCellValue(gv.FocusedRowHandle, gv.Columns[0]));
#endregion
try
{
con.Open();
cmd.ExecuteNonQuery();
}
catch (Exception xe)
{
MessageBox.Show(xe.Message);
}
}
}
This will add more security and allow you to test the stored procedure separately with different parameters. You can even add more checks in the stored procedure call - like checks for column names exist.
In terms of sql injection attacks in the way you're doing it, there's not much more you can do.
I was able to find the simplest way to solve my issue and was as follows:
I failed to notice that when I created the bound between the datagrid and the database a tableAdapter and dataSet was automatically created. With this link as reference I found that adapter had an update method, so I used the information so I simply used this code and it worked like a charm, I also added the line to validate the field wich, to be honest I think is not needed.
Validate(); //Or this.Validate();
tb_AlumnoTableAdapter.Update(escuelaDataSet.tb_Alumno);
As before, I put this code under the 'CellValueChanged' event but I assume I can atach it to a button to make it a save button. Thanks to everyone for your answers and I hope this helps other like me.
You may also like to read: How to: Update Data by Using a TableAdapter.

C# and saving date field to MS Access database

I am new to Access and saving data to it. I have a date time field which I used in Visual Studio to make the form and chose date time picker. I am not sure where I am going wrong but I know it is the calendar picker causing the issue. I get error syntax error in insert to statement.
Here is the code I have
string When = qaWhendateTimePicker.Value.ToString("HH:mm:ss.fff");
then my save query
SQLString = "INSERT INTO QAAnswers (QuestionID,CallMonitorNumber,When) VALUES('"+QuestionID + "','" + CallMonitorNumber + "','" + When + "');";
This is of course the shorten version. But for the love of me if I take out the when it saves to the database fine
The Access database I have WHEN SET AS DATE / TIME.
Should I have it set to text? I would think no because then I can not pull queries based on date.
Thanks in advance as I been at this for many hours.
UPDATE
Per comment below i have changed the syntax. Here is what i have. If i put the .value or .date it does not work. I am sure it is something I am doing wrong. I get the error failed to convert parameter value from datetimepicker to datetime. Thanks as I am learning a lot doing this in access.
ad.InsertCommand = new OleDbCommand("insert into QAAnswers ([CallMonitorNumber],[When],[ProperGreeting],[AssureHelp],[AccountVerification],[ConfirmCaller],[ProperPoliciesSolutions],[ProperPoliciesAdmin],[AppropriateTools],[TroubleshootingSteps],[ConfirmResolved],[CustomerEducation],[CSATSurvey],[ThanksCallerBrand],[ProfessionalToneAttitude],[CustomerInvolved],[CallPace],[Empathy],[PhoneEtiquette],[DiffuseEscalated],[UnacceptableCallPractice],[Notes],[ScorePotential],[ScoreActual],[FinalScore]) values (#CallMonitorNumber,#When,#ProperGreeting,#AssureHelp,#AccountVerification,#ConfirmCaller,#ProperPoliciesSolutions,#ProperPoliciesAdmin,#AppropriateTools,#TroubleshootingSteps,#ConfirmResolved,#CustomerEducation,#CSATSurvey,#ThanksCallerBrand,#ProfessionalToneAttitude,#CustomerInvolved,#CallPace,#Empathy,#PhoneEtiquette,#DiffuseEscalated,#UnacceptableCallPractice,#Notes,#ScorePotential,#ScoreActual,#FinalScore)", con);
ad.InsertCommand.Parameters.Add("#QuestionID", OleDbType.VarChar).Value = agentIDNumbertextBox.Text.ToString();
ad.InsertCommand.Parameters.Add("#CallMonitorNumber", OleDbType.VarChar).Value = qaCallMonitorNumbertextBox.Text.ToString();
ad.InsertCommand.Parameters.Add("#When", OleDbType.DBDate).Value = qaWhendateTimePicker;
UPDATED ANSWER
I finally figured it out. Not sure if this is the best way but i just ignored the datetimepicker. I wish i could use the datepicker. Instead i just input the date it was added in by using this statement (shorten version ) Notice the [when] and the Date() .
DateTime now = DateTime.Now;
ad.InsertCommand = new OleDbCommand("insert into QAAnswers ([CallMonitorNumber],[When]) values (#CallMonitorNumber,Date())", con);
I hope this helps someone else. I really do not like using access for a DB but that is what i have to work with .
I gave points to marc as i never heard of parametrized query
You should use a parametrized query to do the insert, to avoid SQL injection attacks!
Something like this:
SQLString = "INSERT INTO QAAnswers (QuestionID, CallMonitorNumber, When) VALUES(?, ?, ?);";
and then when you prepare your insert statement, you need to add three parameters (in Access typically defined as p1, p2, p3) and assign values to those.
using (OleDbConnection conn = new OleDbConnection(YourConnectionStringHere))
using (OleDbCommand cmd = new OleDbCommand(SQLString, conn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("p1", OleDbType.VarChar, 50).Value = QuestionID;
cmd.Parameters.Add("p2", OleDbType.VarChar, 50).Value = CallMonitorNumber;
cmd.Parameters.Add("p3", OleDbType.DBDate).Value = When;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
This will also take care of avoiding issues with dates in string format, and issues with single quotes and all those messy things.
You can use this method also:-
write your insert query in a stored procedure(or you can use query directly) then call it in your method
string strcon = ConfigurationManager.ConnectionStrings["YourConnectionStringName"].ConnectionString;
con.ConnectionString = strcon;
con.Open();
SqlCommand cmd = new SqlCommand("[Your_StoredProcedureName]", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.AddWithValue("#value1", value1);
da.SelectCommand.Parameters.AddWithValue("#value2", value2);
da.SelectCommand.Parameters.AddWithValue("#value3", value3);
int result = da.SelectCommand.ExecuteNonQuery();
return result ;
I finally figured it out. Not sure if this is the best way but i just ignored the datetimepicker. I wish i could use the datepicker. Instead i just input the date it was added in by using this statement (shorten version ) Notice the [when] and the Date() .
DateTime now = DateTime.Now;
ad.InsertCommand = new OleDbCommand("insert into QAAnswers ([CallMonitorNumber],[When]) values (#CallMonitorNumber,Date())", con);

How can I obtain a value from a stored procedure (SELECT COUNT) in c#

I'm using a stored procedure to count and validate if a username already exists in the database, but the problem isn't there, my problem is when I try to obtain the value of the SELECTION in C# in some blogs I found this code:
// Create ConnectionString
string connectionString = ConfigurationManager.ConnectionStrings["ProjectPractice"].ConnectionString;
// Check if the username is not in the DataBase
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmo = new SqlCommand("spBuscaUsuarioMail", con);
cmo.CommandType = CommandType.StoredProcedure;
cmo.Parameters.AddWithValue("#Username", 1);
SqlParameter NroUserName = new SqlParameter("#Num_de_Usuarios", 0);
NroUserName.Direction = ParameterDirection.Output;
cmo.Parameters.Add(NroUserName);
con.Open();
int contarUsername = Int32.Parse(cmo.Parameters["#Num_de_Usuarios"].Value.ToString());
This seems to be great! And it looks like function very well but then in the last part int contarUsername = Int32.Parse... C# gives me an exception that is the next:
NullReferenceException was unhandled by user code.
Object reference not set o an instance of an object.
Then, in troubleshooting tips I read:
Check to determine if the object is null before calling the method.
Use the "new keyword to create an object instance.
Get general help for this exception.
I tried a lot of things, but now I feel really tired and I can't think in a new solution.
This is the stored procedure I'm using:
CREATE PROCEDURE spBuscaUsuarioMail
#Username CHAR (25),
#Num_de_Usuarios INT OUTPUT
AS
BEGIN
SET NOCOUNT ON
SELECT #Num_de_Usuarios = COUNT (UserName)
FROM dbo.Usuarios
WHERE UserName = #Username
END
EXEC spBuscaUsuarioMail '1', #Num_de_Usuarios OUTPUT
SELECT #Num_de_Usuarios
There's something wrong with your parameters....
In the stored procedure, you have
#Username CHAR (25),
#Num_de_Usuarios INT OUTPUT
yet in your C# code, you set up both of them as int, it seems:
cmo.Parameters.AddWithValue("#Username", 1);
SqlParameter NroUserName = new SqlParameter("#Num_de_Usuarios", 0);
NroUserName.Direction = ParameterDirection.Output;
cmo.Parameters.Add(NroUserName);
I think you need to set up the #Username parameter as a string - and give it some meaningful value!
cmo.Parameters.Add("#Username", SqlDbType.Char, 25).Value = "Steve"; // or whatever
And of course, as #Steve already mentioned: you need to actually execute your stored procedure before you can read out the OUTPUT parameter!
If you don't execute the command it is really difficult to get the value of an output parameter
cmo.Parameters.Add(NroUserName);
con.Open();
cmo.ExecuteNonQuery();
int contarUsername = Convert.ToInt32(cmo.Parameters["#Num_de_Usuarios"].Value);
Also the last two lines of the Stored procedure, if they are really in the sp code are meaningless, you don't need them and you get a recursive call on the same stored procedure until somethink breaks . You should remove them
-- remove these two lines
EXEC spBuscaUsuarioMail '1', #Num_de_Usuarios OUTPUT
SELECT #Num_de_Usuarios
Also look at the answer from #marc_s, he points to another problem in your code.
This is the solution. It works!
string connectionString = connectionString = ConfigurationManager.ConnectionStrings["ProjectPractice"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmo = new SqlCommand("spBuscaUsuario", con);
cmo.CommandType = CommandType.StoredProcedure;
cmo.Parameters.Add("#Username", SqlDbType.Char, 25).Value = txtUsername.Text;
SqlParameter NroUserName = new SqlParameter("#Num_de_Usuarios", 0);
NroUserName.Direction = ParameterDirection.Output;
cmo.Parameters.Add(NroUserName);
con.Open();
cmo.ExecuteNonQuery();
int contarUsername = Int32.Parse(cmo.Parameters["#Num_de_Usuarios"].Value.ToString());
And this is the Stored Procedure...
CREATE PROCEDURE spBuscaUsuario
#Username CHAR (25),
#Num_de_Usuarios INT OUTPUT
AS
BEGIN
SET NOCOUNT ON
SELECT #Num_de_Usuarios = COUNT (UserName)
FROM dbo.Usuarios
WHERE UserName = #Username
END
I expect this code be useful for someone else.

Error on SQL Server Insert stored procedure

I'm trying to simply insert data into a table in SQL Server from a C# winforms application.
Currently when the executing the query I'm receiving the error:
Incorrect syntax near 'soAddItems'
Here is my insert code of the class handling my database CRUD operations:
Note: As test data:
itemName = "test"
skuNo = "a123"
itemPrice = 2.99
stockItemToAdd = 3
itemPic = "C:\Users\Name\Pictures\pic.png"**
Code:
public virtual void AddItem(string itemName, string skuNo, double itemPrice, int stockAmountToAdd, string itemPic)
{
using (SqlConnection open = new SqlConnection(connectionString))
{
SqlCommand insertCommand = new SqlCommand("soAddItems", open);
open.Open();
insertCommand.Parameters.Add("#itemName", SqlDbType.NChar).Value = itemName;
insertCommand.Parameters.Add("#skuNo", SqlDbType.VarChar).Value = skuNo;
insertCommand.Parameters.Add("#itemPrice", SqlDbType.Decimal).Value = itemPrice;
insertCommand.Parameters.Add("#instockAmount", SqlDbType.BigInt).Value = stockAmountToAdd;
insertCommand.Parameters.Add("#lastSold", SqlDbType.DateTime).Value = DateTime.Today;
insertCommand.Parameters.Add("#itemPic", SqlDbType.NChar).Value = itemPic;
//***** Error on the execute*****
insertCommand.ExecuteNonQuery();
};
}
SQL Server stored procedure:
ALTER PROC [dbo].[soAddItems]
#itemName nchar,
#skuNo varchar,
#itemPrice float,
#instockAmount bigint,
#lastSold dateTime,
#itemPic varchar
AS
BEGIN
INSERT INTO items (itemName, skuNo, itemPrice, instockAmount, lastSold, itemPic)
VALUES (#itemName, #skuNo, #itemPrice, #instockAmount, #itemPic)
END
Can anyone tell me where I'm going wrong?
You need to tell the SqlCommand command type as stored procedure.
Try this:
insertCommand.CommandType = CommandType.StoredProcedure;
It looks like you forget to assign your SqlCommand.CommandType property.
Because it is Text as a default.
insertCommand.CommandType = CommandType.StoredProcedure;
Besides the missing CommandType.StoredProcedure, you have a second major flaw: if you define a parameter like this: #skuNo varchar - then you get a string of 1 character length!
That's usually not what you want - you should ALWAYS specify a length when defining parameters and variables in T-SQL!
Use: #skuNo varchar(50) or whatever length you need

Update CLOB using a textbox in C#

I've been all over the web with this one and I am surprised how I can't seem to find any way to do what I looking for.
I am using the Oracle.DataAccess.Client library in my C# project, not the deprecated System.Data.OracleClient.
I have a very simple table:
CREATE TABLE testing (
ID NUMBER(10),
COMMENTS CLOB,
DATECREATED DATE DEFAULT (SYSDATE) NOT NULL,
DATEMODIFIED DATE
);
INSERT INTO testing (ID, COMMENTS) VALUES(1, 'this is a test');
The above obviously works just fine. The problem is, this being a comment field it will be changed. In my C# program I would like to allow users to save comments. For this example I am removing anything complex.
I have a button on a form and a textbox called "comments".
using (OracleConnection connection = new OracleConnection(<VALID CONN STRING GOES HERE>)) {
connection.Open();
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
command.CommandText = "UPDATE testing SET COMMENTS = :COMMENTS, DATEMODIFIED = sysdate WHERE ID = :ID";
command.CommandType = CommandType.Text;
command.Parameters.Add("ID", OracleDbType.Int32, ParameterDirection.Input).Value = 1;
command.Parameters.Add("COMMENTS", OracleDbType.Clob, ParameterDirection.Input).Value = comments.Text;
command.ExecuteNonQuery();
}
}
So basically this code works as long as I don't attempt to write the Clob. If I save the date modified is created as expected. However when I save with the Clob, nothing happens. No error message from oracle, no exception, nothing.
If I forgo parameterization and do it the wrong way:
command.CommandText = "UPDATE testing SET COMMENTS = " + comments.Text + ", DATEMODIFIED = sysdate";
There is no problem. It seems the parameterization is the issue here.
It turns out I was correct in that parameterization was the issue, however I can say it was a very basic mistake. Anyway the statement was actually running perfectly fine but the parameters were being added out of order.
Note how in the following code ID is added last, as it is the last parameter (where clause.)
using (OracleConnection connection = new OracleConnection(<VALID CONN STRING GOES HERE>)) {
connection.Open();
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
command.CommandText = "UPDATE testing SET COMMENTS = :COMMENTS, DATEMODIFIED = sysdate WHERE ID = :ID";
command.CommandType = CommandType.Text;
command.Parameters.Add("COMMENTS", OracleDbType.Clob, ParameterDirection.Input).Value = comments.Text;
command.Parameters.Add("ID", OracleDbType.Int32, ParameterDirection.Input).Value = 1;
command.ExecuteNonQuery();
}
}
In order to use the binding out of order for ODP .NET, you need to specify this extra command (better practice) This was not required if you had previously used Microsoft's provider.
Command.BindByName=true;
Can you test your update with > 32K in the comment to see if it errors?
From my experience an Oracle CLOB can be written to in this context by converting a String to a character array with the following:
String input = "string value";
OracleParameter parm = new OracleParameter("parameter_name", OracleDbType.Clob);
parm.Direction = ParameterDirection.Input;
parm.Value = input.toCharArray();
as a CLOB is a character large object.

Categories

Resources