I have the following method to inserting data into an an access databasewhich works fine but I do get a problem if I try to insert text that contains single quotes I have learned.
[WebMethod]
public void bookRatedAdd(string title, int rating, string review, string ISBN, string userName)
{
OleDbConnection conn;
conn = new OleDbConnection(#"Provider=Microsoft.Jet.OleDb.4.0;
Data Source=" + Server.MapPath("App_Data\\BookRateInitial.mdb"));
conn.Open();
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = #"INSERT INTO bookRated([title], [rating], [review], [frnISBN], [frnUserName])VALUES('" + title + "', '" + rating + "','" + review + "','" + ISBN + "', '" + userName + "')";
cmd.ExecuteNonQuery();
conn.Close();
}
From what I understand one of the ways to solve the problem is by using parameters. I am not sure how to do this to be honest. How could I change the above code so that I insert the data by using parameters instead?
Same as for any other query:
a) Replace actual hardcoded parameters in your OleDbCommand with placeholders (prefixed with #),
b) Add instances of OleDbParameter to the DbCommand.Parameters property. Parameter names must match placeholder names.
[WebMethod]
public void bookRatedAdd(string title, int rating, string review, string ISBN, string userName)
{
using (OleDbConnection conn = new OleDbConnection(
"Provider=Microsoft.Jet.OleDb.4.0;"+
"Data Source="+Server.MapPath("App_Data\\BookRateInitial.mdb"));
{
conn.Open();
// DbCommand also implements IDisposable
using (OleDbCommand cmd = conn.CreateCommand())
{
// create command with placeholders
cmd.CommandText =
"INSERT INTO bookRated "+
"([title], [rating], [review], [frnISBN], [frnUserName]) "+
"VALUES(#title, #rating, #review, #isbn, #username)";
// add named parameters
cmd.Parameters.AddRange(new OleDbParameter[]
{
new OleDbParameter("#title", title),
new OleDbParameter("#rating", rating),
...
});
// execute
cmd.ExecuteNonQuery();
}
}
}
You have to use Parameter to insert Values. Its is allso a security Issue.
If you do it like that a sql injection could by made.
Try like this:
string ConnString = Utils.GetConnString();
string SqlString = "Insert Into Contacts (FirstName, LastName) Values (?,?)";
using (OleDbConnection conn = new OleDbConnection(ConnString))
{
using (OleDbCommand cmd = new OleDbCommand(SqlString, conn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("FirstName", txtFirstName.Text);
cmd.Parameters.AddWithValue("LastName", txtLastName.Text);
conn.Open();
cmd.ExecuteNonQuery();
}
}
For Microsoft Access the parameters are positional based and not named, you should use ? as the placeholder symbol although the code would work if you used name parameters provided they are in the same order.
See the documentation for OleDbCommand.Parameters Property
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.
Be sure to include the expected schema type where the parameter will be used AND the schema length if applicable.
I also recommend you always use using statements around your instances where the type implements IDisposable like the OleDbConnection so that the connection is always closed even if an exception is thrown in the code.
Changed Code:
var connectionStringHere = #"Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + Server.MapPath("App_Data\\BookRateInitial.mdb";
using (var conn = new OleDbConnection(connectionStringHere))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO bookRated ([title], [rating], [review], [frnISBN], [frnUserName]) VALUES(?, ?, ?, ?, ?)";
cmd.Parameters.Add(new OleDbParameter("?", OleDbType.VarChar, 100) { Value = title});
cmd.Parameters.Add(new OleDbParameter("?", OleDbType.Integer) { Value = rating });
cmd.Parameters.Add(new OleDbParameter("?", OleDbType.VarChar, 2000) { Value = review });
cmd.Parameters.Add(new OleDbParameter("?", OleDbType.VarChar, 60) { Value = ISBN });
cmd.Parameters.Add(new OleDbParameter("?", OleDbType.VarChar, 256) { Value = userName });
conn.Open();
var numberOfRowsInserted = cmd.ExecuteNonQuery();
}
Related
I want to insert C# winform values to Mysql
there are 3 columns
name,id are TextBox text and gender is ComboBox value
but there is error and error messsage said: MySql.Data.MySqlClient.MySqlException: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '',')' at line 1'
what code should i fix?
using (MySqlConnection conn2 = new MySqlConnection(strconn))
{
conn2.Open();
string query = "INSERT INTO student1(name,id,gender) values ('" + name3.Text + "'," + id3.Text + "'," + gender3.SelectedValue+"');";
MySqlCommand cmd = new MySqlCommand(query, conn2);
cmd.ExecuteNonQuery();
}
You're missing a single quote in the connecting string literal between name3.Text and id3.Text and again between id3.Text and gender3.SelectedValue
But it shouldn't matter. If you're concatenating user-supplied strings like this it's only a matter of time until your system is breached. There's a better way that avoids this risk, makes it easier to get your SQL statements correct, and runs faster.
//This could be marked const!
string query = "INSERT INTO student1(name,id,gender) values (#name, #id, #gender);";
using (var conn2 = new MySqlConnection(strconn))
using (var cmd = new MySqlCommand(query, conn2))
{
//I have to guess, but you can find exact column types/lengths from your db
//Do not use AddWithValue()!
// MySql is less at risk for the AddWithValue() performance issues
// than Sql Server but the risk isn't completely eliminated.
cmd.Parameters.Add("#name", MySqlDbType.VarChar, 30).Value = name3.Text;
cmd.Parameters.Add("#id", MySqlDbType.VarChar, 50).Value = id3.Text;
cmd.Parameters.Add("#gender", MySqlDbType.VarChar, 5).Value = gender3.SelectedValue;
conn2.Open();
cmd.ExecuteNonQuery();
}
using (MySqlConnection conn2 = new MySqlConnection(strconn))
{
String query = "INSERT INTO student1(name,id,gender) values (#name,#id,#gender)";
MySqlCommand = new MySqlCommand(query, conn2);
command.Parameters.AddWithValue("#name", name3.Text);
command.Parameters.AddWithValue("#id", id3.Text);
command.Parameters.AddWithValue("#gender", gender3.SelectedValue.ToString());
command.ExecuteNonQuery();
}
use need use parameters
As a group we are working on a project and need to save the data collected in the label in a field in an access database. However we have been having some troubles with this function.
Here is the code what i have tried so far:
We changed the values from lbl.View.text to "1" for testing purposes, but still no luck.
private void complete_btn_Click(object sender, EventArgs e)
{
string connStr = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\meSch\log.accdb;Persist Security Info=True";
OleDbConnection con = new OleDbConnection();
con.ConnectionString = connStr;
OleDbCommand cmd = con.CreateCommand();
// error is in insert statement somehwhere.
cmd.CommandText = "INSERT INTO Users (TimeStamp, Interest, TotalTime)" + "VALUES('" + "1" +"', '"+ "1" + "','" + "1" + "');";
// conn1 = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\meSch\log.accdb;Persist Security Info=True");
// cmd = new OleDbCommand("", con);
// cmd.Parameters.AddWithValue("#TimeStamp", lblView.Text);
// cmd.Parameters.AddWithValue("#Interest", lblView.Text);
// cmd.Parameters.AddWithValue("#TotalTime", lblView.Text);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
Based on your exception message, TimeStamp is a reserved keyword in MS Access. You need to use it with square brackets like [TimeStamp]. As a better way, change it to non-reserved word which is meaningful for your column.
But more important, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Also use using statement to dispose your OleDbConnection and OleDbCommand.
using(OleDbConnection con = new OleDbConnection(conString))
using(OleDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = #"INSERT INTO Users (TimeStamp, Interest, TotalTime)
VALUES(?, ?, ?)";
cmd.Parameter.AddwithValue("#p1", "1");
cmd.Parameter.AddwithValue("#p2", "1");
cmd.Parameter.AddwithValue("#p3", "1");
con.Open();
cmd.ExecuteNonQuery();
}
I have this method for Editing data but I don't know how to write the code... Until now I have this which I don't really understand and I have an error in it. It says incorrect syntax near '('.
public void EditMember(Member member)
{
string Name = member.Name;
string Surname = member.Surname;
string EntryDate = member.EntryDate.ToString("dd.MM.yyyy");
string Status = member.Status;
sqlConnection.Open();
sqlCommand = new SqlCommand(
"UPDATE Members SET (Name, Surname, EntryDate) VALUES('" + Name + "','" + Surname + "','" + EntryDate + "')' WHERE'(' Id '='" + member.Id + "')",
sqlConnection);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
}
The problem is when I start to write WHERE
Help please.
Please read all of this answer, not just the first part
There are multiple issues here. The most immediate problem is here:
"')' WHERE'('
That's acting as if you're trying to quote the bracket. That "should" be:
"') WHERE ('
At that point it would look like a valid (but bad) INSERT command... but your use of VALUES which doesn't look like it's a valid way of updating in T-SQL anyway.
However, you shouldn't use this approach at all. It's error-prone, hard to read, and most importantly prone to SQL injection attacks.
Instead, you should use parameterized SQL:
string sql = #"UPDATE Members
SET Name = #Name, Surname = #Surname, EntryDate = #EntryDate
WHERE Id = #Id";
using (var connection = new SqlConnection(...))
{
connection.Open();
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#Name", SqlDbType.NVarChar).Value = member.Name;
command.Parameters.Add("#Surname", SqlDbType.NVarChar).Value = member.Surname;
command.Parameters.Add("#EntryDate", SqlDbType.DateTime).Value = member.EntryDate;
command.Parameters.Add("#Id", SqlDbType.NVarChar).Value = member.Id;
int rows = command.ExecuteNonQuery();
// TODO: Work out what to do if rows isn't 1
}
}
(With adjustments for the appropriate data types, of course.)
You should NEVER EVER concatenate together your SQL statements with user input.
Instead : use parametrized queries - they're easy to use, avoid SQL injection, and improve performance.
Try code something like this:
string updateStmt = "UPDATE dbo.Members SET Name = #Name, Surname = #Surname, EntryDate = #EntryDate WHERE Id = #ID";
sqlCommand = new SqlCommand(updateStmt, sqlConnection);
sqlCommand.Parameters.Add("#Name", SqlDbType.VarChar, 100).Value = name;
sqlCommand.Parameters.Add("#Surname", SqlDbType.VarChar, 100).Value = surname;
sqlCommand.Parameters.Add("#EntryDate", SqlDbType.DateTime).Value = entrydate;
sqlCommand.Parameters.Add("#ID", SqlDbType.Int).Value = member.Id;
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
The correct syntax for an update statement is
"UPDATE Members SET Name = #name, Surname = #surname, EntryDate = #date WHERE id=#id"
Said that, you should use parameterized query like this
public void EditMember(Member member)
{
string Name = member.Name;
string Surname = member.Surname;
string EntryDate = member.EntryDate.ToString("dd.MM.yyyy");
string Status = member.Status;
sqlConnection.Open();
sqlCommand = new SqlCommand("UPDATE Members SET Name = #name, Surname = #surname, " +
"EntryDate = #date " +
"WHERE Id = #id", sqlConnection);
sqlCommand.Parameters.AddWithValue("#name", Name);
sqlCommand.Parameters.AddWithValue("#surname", Surname);
sqlCommand.Parameters.AddWithValue("#date", EntryDate);
sqlCommand.Parameters.AddWithValue("#id", Status);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
As a side note, keep in mind that AddWithValue is a simple way to add parameters to you query, but if the perfomance of this query is critical it is better to use a fully defined parameter with the datatype that matches exactly your database column's type and with the exact size.
Remove the quotes from around the WHERE and you should be fine. Please heed the warnings given in the comments about SQL injection attacks.
Your code has syntax error for update and also SQLInjection issue.
You need to pass parameters to update query rather than passing direct values.
It should be as follows:
public void EditMember(Member member)
{
string Name = member.Name;
string Surname = member.Surname;
string EntryDate = member.EntryDate.ToString("dd.MM.yyyy");
string Status = member.Status;
sqlConnection.Open();
sqlCommand = new SqlCommand("UPDATE Members SET Name=#Name, Surname=#Sirname, EntryDate=#EntryDate WHERE Id = #id", sqlConnection);
sqlCommand.parameters.AddparameterWithValue("#Name",Name);
sqlCommand.parameters.AddparameterWithValue("#Surname",Surname);
sqlCommand.parameters.AddparameterWithValue("#EntryDate",EntryDate);
sqlCommand.parameters.AddparameterWithValue("#Id",Id);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
}
Edit the post to make correct answer:
i.e. you don't need brackets in where clause. And yes the better query is
"UPDATE Members SET Name=#Name, Surname=#Surname, EntryDate=#EntryDate WHERE Id=#ID"
and then you add #Name, #Surname, .. etc through parameter of command object.
OleDbCommand system = new OleDbCommand();
system.CommandType = CommandType.Text;
system.CommandText = "DELETE FROM Student WHERE(ID= '" +
txtStudentIDnumber.Text + "')";
system.Connection = mydatabase;
mydatabase.Open();
system.ExecuteNonQuery();
dataGridView1.Update();
this.tableAdapterManager.UpdateAll(csharrpfinalprojectDataSet);
mydatabase.Close();
MessageBox.Show("Student Record Deleted.", "deleting record...");
In your command text you need to remove single quotes (') around the txtStudentIDnumber.Text as it appears ID is of type integer and you are passing it as string. Following should fix the error.
system.CommandText = "DELETE FROM Student WHERE(ID= " + txtStudentIDnumber.Text + ")";
EDIT: With respect to #mdb comments, you should always use Parameters in your query so that you can avoid SQL Injection. Consider the following:
OleDbCommand system = new OleDbCommand();
system.CommandType = CommandType.Text;
system.CommandText = "DELETE FROM Student WHERE ID = ?";
OleDbParameter parameter = new OleDbParameter("ID", txtStudentIDnumber.Text);
system.Parameters.Add(parameter);
system.Connection = mydatabase;
mydatabase.Open();
system.ExecuteNonQuery();
dataGridView1.Update();
OleDbCommand system = new OleDbCommand();
system.CommandType = CommandType.Text;
system.CommandText = "DELETE FROM Student WHERE ID=#ID";
system.Parameters.AddWithValue("#ID", txtStudentIDnumber.Text);
system.Connection = mydatabase;
mydatabase.Open();
system.ExecuteNonQuery();
dataGridView1.Update();
this.tableAdapterManager.UpdateAll(csharrpfinalprojectDataSet);
mydatabase.Close();
MessageBox.Show("Student Record Deleted.", "deleting record...");
What will happen when user input for txtStudentIDNumber is,
1 or 1=1
In that case hardcoded SQL string will be,
DELETE FROM Student WHERE(ID=1 or 1=1)
So prefer parameterized sql statement instead of hard-coded string.
using(OleDbConnection cn=new OleDbConnection(cnStr))
{
using(OleDbCommand cmd=new OleDbCommand())
{
cmd.CommandText="DELETE FROM Student WHERE ID=#ID";
cmd.Connection=cn;
cmd.Parameters.Add("#ID",SqlDbType.Int).Value=txtStudentIDnumber.Text;
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
}
I am trying to insert a record and get its newly generated id by executing two queries one by one, but don't know why its giving me the following error.
Object cannot be cast from DBNull to other types
My code is as below: (I don't want to use sql stored procedures)
SqlParameter sqlParam;
int lastInsertedVideoId = 0;
using (SqlConnection Conn = new SqlConnection(ObjUtils._ConnString))
{
Conn.Open();
using (SqlCommand sqlCmd = Conn.CreateCommand())
{
string sqlInsertValues = "#Name,#Slug";
string sqlColumnNames = "[Name],[Slug]";
string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + ");";
sqlCmd.CommandText = sqlQuery;
sqlCmd.CommandType = CommandType.Text;
sqlParam = sqlCmd.Parameters.Add("#Name", SqlDbType.VarChar);
sqlParam.Value = txtName.Text.Trim();
sqlParam = sqlCmd.Parameters.Add("#Slug", SqlDbType.VarChar);
sqlParam.Value = txtSlug.Text.Trim();
sqlCmd.ExecuteNonQuery();
//getting last inserted video id
sqlCmd.CommandText = "SELECT SCOPE_IDENTITY() AS [lastInsertedVideoId]";
using (SqlDataReader sqlDr = sqlCmd.ExecuteReader())
{
sqlDr.Read();
lastInsertedVideoId = Convert.ToInt32(sqlDr["lastInsertedVideoId"]);
}
}
}
//tags insertion into tag table
if (txtTags.Text.Trim().Length > 0 && lastInsertedVideoId > 0)
{
string sqlBulkTagInsert = "";
string[] tags = txtTags.Text.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tag in tags)
{
sqlBulkTagInsert += "INSERT INTO tags(VideoId, Tag) VALUES(" + lastInsertedVideoId + ", " + tag.Trim().ToLowerInvariant()+ "); ";
}
using (SqlConnection Conn = new SqlConnection(ObjUtils._ConnString))
{
Conn.Open();
using (SqlCommand sqlCmd = Conn.CreateCommand())
{
string sqlQuery = sqlBulkTagInsert;
sqlCmd.CommandText = sqlQuery;
sqlCmd.CommandType = CommandType.Text;
sqlCmd.ExecuteNonQuery();
}
}
}
And also if possible, please check is the above code coded well or we can optimize it more for improve performance?
Thanks
The call to SCOPE_IDENTITY() is not being treated as being in the same "scope" as the INSERT command that you're executing.
Essentially, what you need to do is change the line:
string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + ");";
to:
string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + "); SELECT SCOPE_IDENTITY() AS [lastInsertedVideoId]";
and then call
int lastVideoInsertedId = Convert.ToInt32(sqlCmd.ExecuteScalar());
instead of .ExecuteNonQuery and the code block following the "//getting last inserted video id" comment.
The SCOPE_IDENTITY() should be extracted from the first command (SELECT, RETURN or OUT) and passed into the next command. By that, I mean that the SELECT_IDENTITY() should be at the end of the first command. In SQL 2008 there is additional syntax for bring values back as part of the INSERT, which makes this simpler.
Or more efficiently: combine the commands into one to avoid round-trips.