I am having a problem with inserting new data into MS Access 2007 file. It say I am having an incorrect SQL statement.
What is the problem here? I am not good at SQL. Please point out my error.
try
{
// Open database connection.
objOleDbConnection.Open();
objOleDbCommand.CommandText =
"INSERT INTO PersonalData (Type, UserName, Password) VALUES ('" + cmbType.Text + "','" + txtUserName.Text + "','" + txtPassword.Text + "')";
// Execute creating table command.
objOleDbCommand.ExecuteNonQuery();
}
To start with, you need to put quotes around your text data:
#"INSERT INTO PersonalData (Type, UserName, Password) VALUES (" + cmbType.SelectedIndex + ",'" + txtUserName.Text + "','" + txtPassword.Text + "')";
However, you would be much better off converting this to use parameters, since you won't have to worry about embedded quotes:
objOleDbCommand.CommandText = #"INSERT INTO PersonalData (Type, UserName, Password) VALUES (?, ?, ?)";
objOleDbCommand.Parameters.Add("Type", cmbType.SelectedIndex);
objOleDbCommand.Parameters.Add("UserName", txtUserName.Text);
objOleDbCommand.Parameters.Add("Password", txtPassword.Text);
Both Type and Password are reserved words. See Problem names and reserved words in Access.
If you must keep those as the field names, surround them with square brackets in your INSERT statement so the database engine will know to interpret them as fields:
"INSERT INTO PersonalData ([Type], UserName, [Password]) VALUES ...
On that same web page, follow the link for Database Issue Checker Utility. That utility can warn you about problems with reserved words in your application, and other potential troublesome issues.
Edit: If PersonalData includes additional fields which are required and do not have default values assigned, you must include those fields with values in your INSERT statement, or it will definitely fail.
Let's say txtUserName.Text is Foo, and txtPassword.Text is bar. Then you're getting
INSERT INTO PersonalData (Type, UserName, Password) VALUES (3,foo,bar)
instead of the syntactically correct
INSERT INTO PersonalData (Type, UserName, Password) VALUES (3,'foo','bar')
Since you don't have columns foo and bar, you are getting an error - is my assumption. Things get worse if you have baz,moo instead of foo. Or, gods forbid, Bobby Tables.
There a few places where you might encounter problems here.
Type, Username, and Password are all (I think) MS Access keywords. While they seem to work when used within Access istself (like in the Querybuilder, for example), they seem to throw exceptions when used from Client Code. Surround the fieldnames in your SQL Statement with square brackets, so that Access treats them as literals.
I strongly recommend using SQL Parameters for your in-line SQL, and then using ADO.NET Parameters to set the values. Google "SQL Injection Attack" to learn why. Plus, it's just good practive (there are some limited exceptions).
EDIT: Note that with OleDb, the parameters must appear in the same order as the fliednames in the list. THis is not the case with ADO & SQLClient. With Access, however, having your parameters out of order will create difficult-to-find problems . . .
Your SQL would then look like this:
INSERT INTO ([Type], [Username], [Password]) VALUES ( #Type, #UserName, #Password )
And your code might resemble THIS (I took some liberties here . . .
private void InsertUserData(int Type, String UserName, String Password)
{
// The "Using" block handles object creation and disposal -
// handy for unmanaged resources like database connections:
using(OleDbConnection cn = new OleDbConnection(YourConnectionString))
{
using(OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = cn;
// 1. Note the use of Parameters here. This will hinder attempts to
// compromise your app with SQl Injection and/or faulty user input.
// 2. Also note that, since "Type", "Username", and "Password" are all
// MS Access keywords, there is a potential for problems when
// used as fieldnames. Therefore we enclose them
// in square brackets [] in the "INSERT INTO" Clause:
String SQL =
"INSERT INTO PersonalData([Type], [UserName], [Password]) " +
"VALUES(#Type, #UserName, #Password)";
// Set the CommandText Proprty:
cmd.CommandText = SQL;
// Now create some OleDb Parameters:
OleDbParameter prmType = new OleDbParameter("#Type", Type);
OleDbParameter prmUserName = new OleDbParameter("#UserName", UserName);
OleDbParameter prmPassword = new OleDbParameter("#Password", Password);
// Add the params to the parameters collection:
cmd.Parameters.Add(prmType);
cmd.Parameters.Add(prmUserName);
cmd.Parameters.Add(prmPassword);
try
{
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Hope that helps . . .
Related
I have a problem with executing a sql command to the DB. The command should add a new user to the 'users' table.
But when I run the code, I get this Exception on:
command.ExecuteNonQuery();
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.OleDb.OleDbException: Syntax error in INSERT INTO statement.
this is the code of the page - GetSignIn.cshtml :
#{
string Uname = Request["name"];
string userName = Request["userName"];
string pass = Request["passWord"];
string pic = Request["pic"];
string privacy = Request["privacy"];
if(pic == null)
{
pic = "Shared/defaultPic.jpg";
}
System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Etay\Documents\Visual Studio 2012\WebSites\Josef\Shared\users.mdb";
try
{
System.Data.OleDb.OleDbCommand command = new System.Data.OleDb.OleDbCommand();
command.Connection = connection;
connection.Open();
command.CommandText = "INSERT INTO users (userName,passWord,Uname,pic) VALUES ('" + userName + "', '" + pass + "', '" + Uname + "', '" + pass + "', " + pic + ")";
command.ExecuteNonQuery();
Response.Redirect("../HtmlPage.html");
}
finally
{
connection.Close();
}
}
What should I change in my code? Why is it happening? Where is the syntax error in the INSERT INTO?
Use parameterized queries. Here is your statement rewritten to make use of them.
I replaced your try/finally with a using block although your try/finally was acceptable.
Parameterized queries prevent errors and Sql Injection Attacks. An error could occur in your existing code if I were to submit a tick as a part of my user name or password. In the current form this would result in an exception. This is because the tick character is used to quote strings in sql syntax.
using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection())
{
connection.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Etay\Documents\Visual Studio 2012\WebSites\Josef\Shared\users.mdb";
using (System.Data.OleDb.OleDbCommand command = new System.Data.OleDb.OleDbCommand())
{
command.Connection = connection;
command.CommandText = "INSERT INTO users (userName,passWord,Uname,pic) VALUES (?,?,?,?)";
command.Parameters.Add(userName);
command.Parameters.Add(pass);
command.Parameters.Add(Uname);
command.Parameters.Add(pic);
connection.Open();
command.ExecuteNonQuery();
}
}
About parameters for an OleDb connection from OleDbCommand.Parameters
Remarks
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used. For example:
SELECT * FROM Customers WHERE CustomerID = ?
Therefore, the order in which OleDbParameter objects are added to the OleDbParameterCollection must directly correspond to the position of the question mark placeholder for the parameter in the command text.
What should I change in my code?
Change to parameters (that also fixes the problem that you don;t have quotes around the pic value)
Remove the second instance of pass in your values
command.CommandText = "INSERT INTO users (userName,passWord,Uname,pic) VALUES (#userName, #pass, #Uname, #pic)";
command.Parameters.Add("#userName").Value = userName;
.. etc.
It's unclear what the type if pic is - you are passing a string but I can;t tell of the column stores a file path or if you are indending to serialize the file and store it in a pinary field.
You set 4 fields after the "INTO" clause, however you're passing 5 parameters:
"INSERT INTO users (userName,passWord,Uname,pic) VALUES ('" + userName + "', '" + pass + "', '" + Uname + "', '" + pass + "', " + pic + ")";
Just add the fifth field, or remove one parameter from the VALUES part
Please check take a look at your Insert statement, it looks like that you provided password value twice.
The number of query values and the destination fields should be same in an INSERT statement.
You have the wrong number parameters in your insert statement. For clarity, why not use string.Format to keep everything uniform? (Assuming these are all string types)
var rawSql = #"Insert INTO Users (userName,passWord,Uname,pic) VALUES ('{0}','{1}','{2}','{3}')";
command.CommandText = string.Format(rawSql, userName, pass, Uname, pic);
command.ExecuteNonQuery();
However, it also looks like you probably want to include that 5th parameter as well - just extend the format :
var rawSql = #"Insert INTO Users (userName,passWord,Uname,pic, privacy) VALUES ('{0}','{1}','{2}','{3}','{4}')";
command.CommandText = string.Format(rawSql, userName, pass, Uname, pic, privacy);
command.ExecuteNonQuery();
Since most of the answers failed to address the SQL Injection vulnerability, here's an example with parameterized queries. In addition to preventing SQL Injection attacks, it also makes it easier to troubleshoot these types of issues, and you don't need to worry about quoting or not quoting parameters.
System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Etay\Documents\Visual Studio 2012\WebSites\Josef\Shared\users.mdb";
try
{
System.Data.OleDb.OleDbCommand command = new System.Data.OleDb.OleDbCommand();
command.Connection = connection;
connection.Open();
command.CommandText = "INSERT INTO users (userName, passWord, Uname, pic, privacy) VALUES (?, ?, ?, ?, ?)";
command.Parameters.Add(userName);
command.Parameters.Add(pass);
command.Parameters.Add(name);
command.Parameters.Add(pic);
command.Parameters.Add(privacy);
command.ExecuteNonQuery();
Response.Redirect("../HtmlPage.html");
}
finally
{
connection.Close();
}
Tnx 4 the help
It happend to be a problem with the database - you can not apply a INSERT INTO statement where the column name is "password". "password" is a Reserved word
in SQL.
Tnx again,
Etay
I have the following update query in C# using a JET OLEDB connection, connecting to a ms access DB file. The query fails to change the fields, it runs correctly but just 0 rows changed.
I think the problem is how parameters are processed and compared against the DB but have no idea how to fix it.
The "User" column is set as text. I have an insert statement that works perfectly set up in the same fashion with the parameters.
com.CommandText = "UPDATE [ExamMaster] SET [User] = (DLookup('LName', 'Users', 'ID' = '#correctUser') WHERE [User] = '#user'";
com.Parameters.AddWithValue("#correctUser", correctUser);
com.Parameters.AddWithValue("#user", userName);
If I do not use a parameter for the where clause and just insert it into the command string like so:
WHERE [User] = '"+userName+"'";</code>
it will update the DB just fine. What am I missing here?
UPDATE:
With or with single quotes makes no difference and rearranging the order of the parameters does not work either.
The order matters. I "think" in your query user is being called first before the correctUser due to the DLOOKUP function.
com.Parameters.AddWithValue("#user", userName);
com.Parameters.AddWithValue("#correctUser", correctUser);
You don't need to single quote parameters:
WHERE [User] = #user";
and I'll guess that the DLOOKUP doesn't need the single quotes either, just [brackets] if the field name has a space or is a reserved word (which [User] might be).
You will need to change that a bit, try:
OleDbConnection cn = new OleDbConnection(aconnectionstring);
cn.Open();
//testing
int correctUser = 1;
string userName = "1";
OleDbCommand com = new OleDbCommand();
com.Connection = cn;
//You cannot have a parameter in DLookUp
com.CommandText = "UPDATE [ExamMaster] SET [User] = " +
"DLookup('LName', 'Users', 'ID = " + correctUser + "') WHERE [User] = #user";
com.Parameters.AddWithValue("#user", userName);
//You must execute the query
com.ExecuteNonQuery();
I'm writing a method to insert a Student into a local SQL database that contains a table with information about Students:
public void AddStudent(string name, string teachName, string pass)
{
string dbfile = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\Logo.sdf";
SqlCeConnection connection = new SqlCeConnection("Data Source=" + dbfile + "; Password = 'dbpass2011!'");
connection.Open();
SqlCeTransaction transaction = connection.BeginTransaction();
SqlCeCommand command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = "INSERT INTO Students VALUES ('#name', '#id', '#pass', '#tname')";
command.Parameters.Add("#name", name);
command.Parameters.Add("#id", this.ID);
command.Parameters.Add("#pass", MD5Encrypt.MD5(pass));
command.Parameters.Add("#tname", teachName);
command.Prepare();
command.ExecuteNonQuery();
transaction.Commit();
connection.Dispose();
connection.Close();
}
Whenever I use this, it never inserts the data to the table when I look at the contents of the Students table in the database. Originally I had this return an int so I could see how many rows it affected, which it always returned 1, so I know it's working.
I've looked for answers to this, and the answer to similar questions was that the person asking was looking at the wrong .sdf file. I've made sure that I'm looking at the right file.
Any feedback would be much appreciated!
command.CommandText = "INSERT INTO Students VALUES ('#name', '#id', '#pass', '#tname')";
You should remove the extra single quotes - this should be:
command.CommandText = "INSERT INTO Students VALUES (#name, #id, #pass, #tname)";
Also I am not sure why you open a transaction for a single insert - that is also not needed.
You don't need to put single quote to parametrized query, in case of parametrized query the whole data will be parsed as required,
command.CommandText = "INSERT INTO Students VALUES (#name, #id, #pass, #tname)";
Also, its better to set parameter type, size and value explicitly as below:
SqlCeParameter param = new SqlCeParameter("#name", SqlDbType.NVarChar, 100);
param.Value = name; // name is a variable that contain the data of name field
//param.Value = 'Jhon Smith'; //Directly value also can be used
Hope this would be helpful, thanks for your time.
There is most likely an exception being raised in your code; you need to add a try/catch handler and/or debug the application to figure out exactly what is happening.
However, there are at least two issues with your code:
The prepare statement requires the data types of the parameters. From the MSDN documentation:
Before you call Prepare, specify the data type of each parameter in the statement to be prepared. For each parameter that has a variable-length data type, you must set the Size property to the maximum size needed. Prepare returns an error if these conditions are not met.
You need to close the connection before disposing it (this won't affect the insert, however).
I have been working on this school assignment and have gotten to a point at which I have been stuck for a few days now. My ASP.net web page is supposed to allow the user to create an account and login. However, no matter how many times I fill in the Create Account form, it doesn't seem to get added to the database.
Here is my User class, which holds the createAccount Method
public class Userr
{
//Constructor for the Account Creation method(createAccount)
public string createAccount(string strFname, string strLname, string strUname, string address, string city, string state, string phone, string zip, string email,string password)
{
string i="";
string storedProcText = ("INSERT INTO User Values('#ID," +strUname +"','"+strFname +"','"+ strLname +"','"+address +"','"+city +"','"+state+"','"+zip+"','"+phone+"','"+ email +"','"+ password );
ArrayList parms = null;
DataAccess dataAccess = new DataAccess();
int result = dataAccess.insertUpdateData(parms,storedProcText );
i =result.ToString();
return i;
}
public string Login(string strUsername, string strPassword)
{
DataAccess objDA = new DataAccess();
int result = objDA.LoginUser(strUsername, strPassword);
}
}
Here is my method for updating(stored in the dataAccess object/class
//Constructor for the update method
public int insertUpdateData(ArrayList items, String strProcedureName)
{
int i = 0;
string strConn = WebConfigurationManager.ConnectionStrings["TicketsConnectionString"].ConnectionString;
SqlConnection myConnection = new SqlConnection(strConn);
string sqlText = strProcedureName;
SqlCommand myCommand = new SqlCommand(sqlText);
myCommand.Connection = myConnection;
myCommand.CommandType = CommandType.StoredProcedure;
try
{
using (myConnection)
{
myConnection.Open();
i = myCommand.ExecuteNonQuery();
//grdData.DataSource = myReader;
// grdData.DataBind();
}
}
catch (Exception err)
{
}
return i;
}
The User table contains the follwing fields in order: ID, UserID, FirstName,LastName, Address, City, State, Zip,Phone,EmailAddress,Password
Is my SQL statement wrong, or what? I am at the end of my rope here.
So, off the bat, I see a few issues:
You set your myCommand.CommandType = CommandType.StoredProcedure but, the syntax you provided is not a stored proc. A stored proc would take a name value list of params, which is null in your case.
Lets say you didn't mean to use stored procs, in which case, your sql syntax is incorrect. You don't need the #ID parameter, unless you are passing it in (in which case, you didn't set it). It should be something like this (without knowing the structure of your table):
string storedProcText = ("INSERT INTO User Values("'" +strUname +"','"+strFname +"','"+ strLname +"','" + address +"','"+city +"','"+state+"','"+zip+"','"+phone+"','"+ email +"','"+ password + "'");
This is given that the values you are inserting matches your table exactly. If not, you will need to specify the table field names in your query as well, like so:
string storedProcText = ("INSERT INTO User(username, firstName, lastName, field4, field5, field6) Values("'" +strUname +"','"+strFname +"','"+ strLname +"','" + address +"','"+city +"','"+state+"','"+zip+"','"+phone+"','"+ email +"','"+ password + "'");
The way to do this using stored procs is this:
SqlParameter[] parameters = {
new SqlParameter("#param1", SqlDbType.NVarChar, 50),
new SqlParameter("#param2", SqlDbType.VarChar, 100),
new SqlParameter("#param3", SqlDbType.VarChar, 100),
new SqlParameter("#param4", SqlDbType.VarChar, 100),
new SqlParameter("#param5", SqlDbType.VarChar, 100),
new SqlParameter("#param6", SqlDbType.VarChar, 100)
};
parameters[0].Value = strFname;
parameters[1].Value = strLname;
.........
.........
[all the parameters you need]
You need to create a stored proc, also (obviously)
And then you call your dataaccess layer just like you are doing.
Steps for making this work:
1) Don't catch and swallow every exception. The exception will tell you what you are doing wrong here.
2) As Caspar Kleijne points out, you need to put the password in quotes.
3) As I point out, you need to add a parenthesis.
4) You should also use parameterized SQL queries
5) You probably shouldn't be passing the ID,
Here's the corrected SQL string for #2 and #3:
string storedProcText = ("INSERT INTO User Values('#ID,"
+strUname +"','"+strFname +"','"
+ strLname +"','"+address +"','"
+city +"','"+state+"','"
+zip+"','"+phone+"','"
+ email +"','"+ password
+"')" );
It'll take some refactoring to use parameterized queries, and this is a homework project, so I'll leave that as an exercise for you.
So, to start from the beginning, have you stepped through this code with the debugger and determined if it's throwing an exception or returning zero rows modified?
The most worrisome thing is the insertion of the #ID column. If this is an Identity column you shouldn't be inserting this value. If it's not, I don't see you assigning a value to it anywhere.
EDIT:
So as has been mentioned by others here you have some structural issues in you query.
I took your code and threw it in a quick project and here's what your statement looks like.
INSERT INTO User Values('#ID,UserName','FirstName','LastName','123 Some Street','SomeTown','State','54555','555-444-3333','email#email.com','ITS_A_SECRET!
Notice the end of the query. The password field isn't escaped with a closing ' and the param list is not closed with a closing bracket.
A second problem is that #Id field. Is your column in the database an identity field? (It should be) If so, just remove that.
Now, here's the real kicker. Is your table name User? That's a reserved word in SQL server so you'll get errors in your query as is. Format you query like the following and it will work.
string storedProcText = ("INSERT INTO [dbo].[User] Values('" + strUname + "','" + strFname + "','" + strLname + "','" + address + "','" + city + "','" + state + "','" + zip + "','" + phone + "','" + email + "','" + password + "')");
The other issue, as mentioned is that you have the command type set to Stored Procedure when you are not using one.
Modifying you command type to text:
myCommand.CommandType = CommandType.Text;
After I made these modifications and ran your code I ended up with a record in the database.
The most important thing to check right now is that ID field. Is it an identity column? Make sure it is and then remove it from your statement.
In the insert you are trying to insert #ID which first of all most likely would be an identity column, and unless you set IDENTITY_INSERT ON on that table, will throw an exception, second, even if it was not an identity column, you are not providing the parameter definition for the #ID parameter to the command.
Try removing #ID from the insert statement, and pass in everything else, but ID.
As a side note, your SQL Statement is prone to SQL Injection attacks since you're concatenating sql command string and values provided by user into one string. I would recommend using parameters instead the actual values and then adding parameters to the sql command later.
I cannot post everything as a comment , but can you do one thing..
put a break point and take the contents of this string
string storedProcText = ("INSERT INTO User Values('#ID," +strUname +"','"+strFname +"','"+ strLname +"','"+address +"','"+city +"','"+state+"','"+zip+"','"+phone+"','"+ email +"','"+ password );
and paste the value of storeProcText directly in the database and see if it can successfuly run and create a record for you.
break and debug should fix your problem
Please Comment out this statement:
myCommand.CommandType = CommandType.StoredProcedure’;
You can use a sql script directly.
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\login.mdb";
string uname, pass;
uname = textBox1.Text;
pass = textBox2.Text;
OleDbConnection myConnection = new OleDbConnection(connectionString);
myConnection.Open();
string query = "insert into LOGIN_TABLE (UserName, Password) VALUES ('" + textBox1.Text.ToString() + "','" + textBox2.Text.ToString() + "') ";
OleDbCommand myCommand = new OleDbCommand(query, myConnection);
//myCommand.CommandText = query;
OleDbParameter myParm = myCommand.Parameters.Add("#uname", OleDbType.VarChar, 50);
myParm.Value = textBox1.Text;
myParm = myCommand.Parameters.Add("#pass", OleDbType.VarChar, 50);
myParm.Value = textBox2.Text;
myCommand.ExecuteNonQuery();
myConnection.Close();
From the docs for OleDbCommand.Parameters:
The OLE DB .NET Provider does not
support named parameters for passing
parameters to an SQL statement or a
stored procedure called by an
OleDbCommand when CommandType is set
to Text. In this case, the question
mark (?) placeholder must be used.
There's an example on the same page.
However, you're not even using parameters in your SQL query. You're inviting a SQL injection attack by embedding the user input directly into the SQL and then also adding parameters.
Your query should just be:
String query = "insert into LOGIN_TABLE (UserName, Password) VALUES (?, ?)";
It looks like you can still give parameters names, even if they're not used - so just the change above may be enough.
EDIT: Is it possible that UserName or Password are reserved names? Try escaping them - I know in SQL Server it would be [UserName], [Password] but I don't know if that's true in Access. What happens if you try to execute the same SQL in Access, by the way?
The data you are passing as parameters might have single-quotes, ', in it.
Try this textBox2.Text.Replace("'","''") when assigning values to the parameters.
One more thing, it is not necessary to use parameters when handling simple texts and numbers in simple queries.
Your query should be like this.
string query = "insert into LOGIN_TABLE (UserName, Password) VALUES ( #uname, #pass )";
Now after that write your code, and everything will be work for you.
Whenever you are reading value from textbox, use Trim() as textBox.Text.Trim().
Sorry it will be working for SqlConnection.
Thanks