My update query
update tbl_Clients set Username=#Username, Password=#Password where Id=#Id
When I am updating this code in giving error Syntax error in update statement
The reason might because Passowrd is a reserved keyword in MS Access. You should use it with square brackets like [Password]
update tbl_Clients set Username = #Username, [Password] = #Password where Id = #Id
As a best practice, change it to non-reserved word.
By the way, if you using OleDb provider, it doesn't care about the named parameters. It only care about their orders. Since you didn't show your code, I hope you provided your parameters in a same order that you defined in your command. Like;
var cmd = OleDbCommand("update tbl_Clients set Username = #Username, [Password] = #Password where Id = #Id");
cmd.Parameters.Add("#Username", OleDbType.VarChar, 255).Value = Username;
cmd.Parameters.Add("#Password", OleDbType.VarChar, 255).Value = Password;
cmd.Parameters.Add("#Id", OleDbType.Integer).Value = Id;
For MS Access you use a question mark ("?") in order to reference parameters in a query, so:
update tbl_Clients set Username=?, Password=? where Id=?
Of course you must be careful to add the parameters to the command object in the same order as they appear in the query. See this blog post for some examples.
Related
All - thanks in advance for your time. So, background info - I am trying to create a form for contact registration using C# to pass the information into my MySql DB. If I use the query directly in the code, it works. However, I have read that you should use a stored procedure for security. So, working code is:
using (MySqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = #"INSERT INTO Contacts (contactID,last_name,first_name,address,city,state,zip_code,email_address,newsletter,is_Cell) VALUES (#ciD,#ln, #fn, #add, #city, #state, #zip, #email, #news, #cell)";
//cmd.CommandText = "insert_contact";
//cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("#cID", MySqlDbType.VarChar);
cmd.Parameters.Add("#ln", MySqlDbType.VarChar);
cmd.Parameters.Add("#fn", MySqlDbType.VarChar);
cmd.Parameters.Add("#add", MySqlDbType.VarChar);
cmd.Parameters.Add("#city", MySqlDbType.VarChar);
cmd.Parameters.Add("#state", MySqlDbType.VarChar);
cmd.Parameters.Add("#zip", MySqlDbType.VarChar);
cmd.Parameters.Add("#email", MySqlDbType.VarChar);
cmd.Parameters.Add("#news", MySqlDbType.Bit);
cmd.Parameters.Add("#cell", MySqlDbType.Bit);
cmd.Parameters["#cID"].Value = default;
cmd.Parameters["#ln"].Value = lastName_TextBox.Text;
cmd.Parameters["#fn"].Value = firstName_TextBox.Text;
cmd.Parameters["#add"].Value = address_TextBox.Text;
cmd.Parameters["#city"].Value = city_TextBox.Text;
cmd.Parameters["#state"].Value = state_DropDown.Text;
cmd.Parameters["#zip"].Value = zipCode_TextBox.Text;
cmd.Parameters["#email"].Value = email_TextBox.Text;
cmd.Parameters["#news"].Value = newsletter_CheckBox.Checked;
cmd.Parameters["#cell"].Value = cell_CheckBox.Checked;
cmd.ExecuteNonQuery();
conn.Close();
However, when I change the following lines to this, I get the "cannot be NULL error":
conn.Open();
//cmd.CommandText = #"INSERT INTO Contacts (contactID,last_name,first_name,address,city,state,zip_code,email_address,newsletter,is_Cell) VALUES (#ciD,#ln, #fn, #add, #city, #state, #zip, #email, #news, #cell)";
cmd.CommandText = "insert_contact";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
My stored procedure on the DB is (I suspect this is where the error may be):
BEGIN
INSERT INTO Contacts (contactID,last_name,first_name,address,city,state,zip_code,email_address,newsletter,is_Cell)
VALUES (#ciD,#ln, #fn, #add, #city, #state, #zip, #email, #news, #cell);
END
I have attempted the following, with the accompanying errors:
• Changed the "#" in the stored procedures to a "?" -(Get an error in SQL Syntax)
• Changing all of the columns to accept a NULL value. -(All columns then have a NULL value).
My apologies if this is something easy - just starting out learning.
Thanks in advance!
Pherix
Your insert_contact stored procedure have to provide the parameters (with the type) as below:
CREATE PROCEDURE insert_contact
(
IN cID VARCHAR,
IN ln VARCHAR(30),
IN fn VARCHAR(45),
IN `add` VARCHAR(30),
IN city VARCHAR(30),
IN state VARCHAR(10),
IN zip VARCHAR(20),
IN email VARCHAR(45),
IN news bit,
IN cell bit,
)
BEGIN
INSERT INTO Contacts
(contactID,last_name,first_name,address,city,state,zip_code,email_address,newsletter,is_Cell)
VALUES
(#cID, #ln, #fn, #add, #city, #state, #zip, #email, #news, #cell);
END
And in case there is any parameter which conflict with MySQL reserved words, you need to escape the reserved words with single quotes.
Note:
Your contactID column was int(11) type but you provide the cID parameter as VARCHAR type. You need to take concern that the column type was unmatched and possible lead an exception.
Reference
MySQL - Working with Stored Procedures
Ok, finally found what the Stored Procedure liked:
BEGIN
INSERT INTO Contacts
(last_name,first_name,address,city,state,zip_code,email_address,newsletter,is_Cell)
VALUES
(ln, fn, address, city, state, zip, email, news, cell);
END
Apparently, it did not like the "#" in front of the passed values.
I am passing the parameter like in C# page,
conn.Open();
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.CommandText = commandtype.storedprocedure;
cmd.Parameters.AddWithValue("?user", user)
cmd.Parameters.AddWithValue("?name", name);
On the mysql stored procedures used 2 parameter for record exists finds
#id integer,
#name varchar(200)
BEGIN
IF EXISTS (SELECT * FROM usertable WHERE id = #id and mode =0 limit 1 )
THEN
UPDATE usertable SET name = name where id=#id and mode = 0;
ELSE
INSERT INTO usertable (name, mode)VALUES (#name`enter code here`,0);
END IF;
END
Another way of sending variables to a stored proc that I've used with no problem:
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#name", SqlDbTpye.Varchar).Value = name;
I think you can specify variable by size and type like this:
SqlDbTpye.Varchar,200
But not able to test that right now.
You need to make sure the prefixes for the parameters match. If you use "#" in your stored procedure, you need to use "#" in C#, too, not "?".
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#user", user)
cmd.Parameters.AddWithValue("#name", name);
I am inserting into a database using a stored procedure and i am getting the error:
Procedure or function 'sp_Addrecord' expects parameter '#RecordNumber', which was not supplied.
RecordNumber is an auto incrementing ID so i understand id have to omit it from my insert command and specify which columns and where i have to insert to avoid this but i am calling the procedure which is handled by another class so where would i be able to specify this as you would normally say something like this:
SqlCommand cmd = new SqlCommand("INSERT INTO CARS (carDate, carTime) Values (#Date, #Time)", conDatabase);
Here is my code, i avoided the using statement for simplicity of this example:
List<CarRecord> carRecords;
private void Save_Record_Click(object sender, RoutedEventArgs e)
{
SqlConnection conDatabase = new SqlConnection(String.Format(#"Data Source={0};Initial Catalog={1};Persist Security Info=True;User ID={2};Password={3}", SQLFunctions.connectSQL.SQLSERVER_ID, SQLFunctions.connectSQL.SQLDatabaseName, SQLFunctions.connectSQL.SQLServerLoginName, SQLFunctions.connectSQL.SQLServerPassword));
conDatabase.Open();
SqlCommand cmd = new SqlCommand("sp_Addrecord", conDatabase);
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
conDatabase.Close();
}
public bool Addrecord(CarRecord DataRecord)
{
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
}
EDIT - Stored Procedure:
USE [SDC Logging]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_Addrecord]
#RecordNumber int,
#Date nvarchar(50),
#Time nvarchar(50),
AS
BEGIN
SET NOCOUNT ON;
WITH [source](RecordNumber, Date, Time)
AS
(
SELECT #RecordNumber, #Date, #Time,
)
MERGE dbo.Bags AS [target] USING [source]
ON [target].Date = [source].Date
WHEN MATCHED THEN UPDATE SET
[target].Date = #Date,
[target].Time = #Time,
WHEN NOT MATCHED THEN
INSERT ( Date, Time, )
VALUES( #Date, #Time, );
SELECT SCOPE_IDENTITY()
END
The error says it all. Your sp_Addrecord has a parameter specified that you are supplying. Basically, the parameters you specify here...
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
must match the name and datatype of the parameters defined by sp_Addrecord stored procedure. In addition, make sure your stored procedure's query matches this query...
INSERT INTO CARS (carDate, carTime) Values (#Date, #Time)
Edit based on your Edit
You need to specified the #RecordNumber parameter here...
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#RecordNumber", SqlDbType.Int, DataRecord.recordNumber),
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
Don't worry about the insert just make sure that when inserting you pass a "invalid record number" such as -1, if the MERGE statement doesn't find the record with id of -1 it will successfully insert the record with an auto-generated Id with the help of your identity column
Try This.
You don't need to call separate method Addrecord.
However, you still want to use a separate method. Add code below in the AddRecord method and remove existing code:
SqlParameter []parms = new SqlParameter[1];
parms[0] = new SqlParameter("#Date",DataRecord.carDate) ;
parms[1] = new SqlParameter("#Time",DataRecord.carTime) ;
cmd.Parameters.AddRange(parms);
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
conDatabase.Close();
I am using MS access 2010 and try to connect it using C# windows application and use this code to update the data,
com.CommandText = "UPDATE Admin SET UserName = #UN, Password = #Pass, ValidID = #VID WHERE ID = #ID";
com.Parameters.AddWithValue("#UN", TBUserName.Text);
com.Parameters.AddWithValue("#Pass", TBPassword.Text);
com.Parameters.AddWithValue("#VID", CBvalidation.SelectedValue);
com.Parameters.AddWithValue("#ID", CBEmpName.SelectedValue);
ds.Tables.Add("Admin");
da.Fill(ds, "Admin");
in run time the error that appears is
"Syntax error in UPDATE statement"
So please could u tell me where is the error?
PASSWORD is a reserved keyword in Access JET/SQL.
You need to encapsulate it with square brackets
com.CommandText = "UPDATE Admin SET UserName = #UN, " +
"[Password] = #Pass, ValidID = #VID WHERE ID = #ID";
If it is possible, I suggest you to change the name of this field.
You will have always this problem for every future query on this table.
Try this
com.CommandText =
"UPDATE Admin SET UserName = #UN, [Password] = #Pass, ValidID = #VID WHERE ID = #ID";
You can't use Password as it is reserved instead used [Password]
PASSWORD is a reserved keyword on Access.
Use it with square brackets like [PASSWORD]
com.CommandText = "UPDATE Admin SET UserName = #UN, [Password] = #Pass, ValidID = #VID WHERE ID = #ID";
As a general recomendation, don't use reserved keywords for your identifiers and object names in your database.
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());