The code doesn't produce an exception and seemingly runs fine. But after running it and checking the table i see that the row is not inserted. I use navicat for cheking and that's not the problem. I've double-checked the table name and field names which all correct. What's wrong?
try
{
SQLiteConnection conn = new SQLiteConnection("Data Source=path;Version=3;FailIfMissing=True");
conn.Open();
String sql = "INSERT INTO sales (cust_id, date, cost, price) VALUES ('0', '" + String.Format("{0:u}", DateTime.Now.Date).Split(' ')[0] + "', '" + cost.ToString() + "', '12')";
SQLiteCommand command = new SQLiteCommand(sql, conn);
conn.Close();
}
catch (Exception err)
{
MessageBox.Show(err.Message.ToString());
}
add:
command.ExecuteNonQuery();
on your code:
...
SQLiteCommand command = new SQLiteCommand(sql, conn);
command.ExecuteNonQuery();
Also it is always better to use parameters on your query
Related
i have a button that when clicked inserts data from textbox and combobox fields into database tables, but every time i insert it gives me "Invalid attempt to call read when reader is closed". How can i get rid of this error. And tips on optimising the code are welcome, because i know im a total noob. thanks
private void btnSave_Click(object sender, RoutedEventArgs e)
{
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query1 = "insert into location(Storage, Shelf, columns, rows) values(" + txtWarehouse.Text + ", " + txtShelf.Text + ", " + txtColumn.Text + ", " + txtRow.Text + ")";
SqlCommand sqlCmd = new SqlCommand(Query1, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
sqlCon.Close();
}
catch (Exception er)
{
MessageBox.Show(er.Message);
}
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query3 = "SELECT LOCATION_ID FROM LOCATION WHERE storage='" + txtWarehouse.Text + "' AND shelf='" + txtShelf.Text + "' AND columns='"
+ txtColumn.Text + "' AND rows='" + txtRow.Text + "'";
SqlCommand sqlCmd1 = new SqlCommand(Query3, sqlCon);
SqlDataReader dr = sqlCmd1.ExecuteReader(); ;
while (dr.Read())
{
string LocationId = dr[0].ToString();
dr.Close();
string Query2 = "insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID) values ('" + txtSku.Text + "','" + txtNimetus.Text + "', '"
+ txtMin.Text + "', '" + txtMax.Text + "', '" + txtQuan.Text + "', '" + LocationId + "', '" + (cbCat.SelectedIndex+1) + "', '" + (cbMail.SelectedIndex+1) + "')";
SqlCommand sqlCmd = new SqlCommand(Query2, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
}
sqlCon.Close();
}
catch (Exception ed)
{
MessageBox.Show(ed.Message);
}
}
Let's try to make some adjustments to your code.
First thing to consider is to use a parameterized query and not a
string concatenation when you build an sql command. This is mandatory
to avoid parsing errors and Sql Injections
Second, you should encapsulate the disposable objects in a using statement
to be sure they receive the proper disposal when you have finished to
use them.
Third, you can get the LOCATION_ID from your table without running a
separate query simply adding SELECT SCOPE_IDENTITY() as second batch to your first command. (This works only if you have declared the LOCATION_ID field in the first table as an IDENTITY column)
Fourth, you put everything in a transaction to avoid problems in case
some of the code fails unexpectedly
So:
SqlTransaction tr = null;
try
{
string cmdText = #"insert into location(Storage, Shelf, columns, rows)
values(#storage,#shelf,#columns,#rows);
select scope_identity()";
using(SqlConnection sqlCon = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(cmdText, sqlCon))
{
sqlCon.Open();
using( tr = sqlCon.BeginTransaction())
{
// Prepare all the parameters required by the command
cmd.Parameters.Add("#storage", SqlDbType.Int).Value = Convert.ToInt32(txtWarehouse.Text);
cmd.Parameters.Add("#shelf", SqlDbType.Int).Value = Convert.ToInt32(txtShelf.Text);
cmd.Parameters.Add("#columns", SqlDbType.Int).Value = Convert.ToInt32(txtColumn.Text );
cmd.Parameters.Add("#rows", SqlDbType.Int).Value = Convert.ToInt32(txtRow.Text);
// Execute the command and get back the result of SCOPE_IDENTITY
int newLocation = Convert.ToInt32(cmd.ExecuteScalar());
// Set the second command text
cmdText = #"insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID)
values (#sku, #nimetus,#min,#max,#qty,#locid,#catid,#ordid)";
// Build a new command with the second text
using(SqlCommand cmd1 = new SqlCommand(cmdText, sqlCon))
{
// Inform the new command we are inside a transaction
cmd1.Transaction = tr;
// Add all the required parameters for the second command
cmd1.Parameters.Add("#sku", SqlDbType.NVarChar).Value = txtSku.Text;
cmd1.Parameters.Add("#nimetus",SqlDbType.NVarChar).Value = txtNimetus.Text;
cmd1.Parameters.Add("#locid", SqlDbType.Int).Value = newLocation;
.... and so on for the other parameters required
cmd1.ExecuteNonQuery();
// If we reach this point the everything is allright and
// we can commit the two inserts together
tr.Commit();
}
}
}
}
catch (Exception er)
{
// In case of exceptions do not insert anything...
if(tr != null)
tr.Rollback();
MessageBox.Show(er.Message);
}
Notice that in the first command I use parameters of type SqlDbType.Int because you haven't used single quotes around your text. This should be verified against the real data type of your table columns and adjusted to match the type. This is true as well for the second command where you put everything as text albeit some of those fields seems to be integer (_location_id_ is probably an integer). Please verify against your table.
The below is my code to insert gridview data into a database. However, using this I want to check and restrict insertion into the database where records have the same name, location, education and salary. If all of these are the same and those already present in database they should not get inserted. If any one column is different then they should get inserted.
protected void btn_insert_Click(object sender, EventArgs e)
{
foreach (GridViewRow g1 in GridView1.Rows)
{
SqlConnection con = new SqlConnection(connStr);
cmd = new SqlCommand("insert command", con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
UploadStatusLabel.Text = "Records Inserted Successfully";
}
I think hitting the database inside a for loop is a very bad idea when you have other options. I'm not tackling this issue in the below sample.
Your code may be subject to SQL Injection, you need to use parameters to pass your values. If someone filled the input with ";DROP TABLE OpenOfficetext;" and they have DROP permissions, it will be a problem if you're just concatenating strings.
To avoid duplicates, you can check first if a similar record exists.
foreach (GridViewRow g1 in GridView1.Rows)
{
string insertCommand = "insert into OpenOfficetext(Name, Location, Education, Salary) values(#p1, #p2, #p3, #p4)";
string selectCommand = "SELECT COUNT(*) FROM OpenOfficetext WHERE Name = #p1 AND Location = #p2 AND Education = #p3 AND Salary = #p4";
SqlConnection con = new SqlConnection(connStr);
SqlCommand cmd = new SqlCommand(selectCommand, con);
con.Open();
cmd.Parameters.AddWithValue("#p1", g1.Cells[0].Text);
cmd.Parameters.AddWithValue("#p2", g1.Cells[1].Text);
cmd.Parameters.AddWithValue("#p3", g1.Cells[2].Text);
cmd.Parameters.AddWithValue("#p4", g1.Cells[3].Text);
if (Convert.ToInt32(cmd.ExecuteScalar()) == 0)
{
cmd.CommandText = insertCommand;
cmd.ExecuteNonQuery();
}
con.Close();
}
please use the below code
if not exist (select * from OpenOfficetext where Name='" + g1.Cells[0].Text + "' and Location='" + g1.Cells[1].Text + "' and Education = '" + g1.Cells[2].Text + "' and Salary = '" + g1.Cells[3].Text + "' )
Begin
SqlConnection con = new SqlConnection(connStr);
cmd = new SqlCommand("insert into OpenOfficetext(Name,Location,Education,Salary) values ('" + g1.Cells[0].Text + "','" + g1.Cells[1].Text + "','" + g1.Cells[2].Text + "','" + g1.Cells[3].Text + "')", con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
End
Not able to insert date into datetime column in sql server.
While debugging after the first executeNonQuery() statement debugger jumps to catch block
and it's displaying the following message in sqlError parameter in catch block:
'Incorrect Syntax near 12'
public ActionResult AddStudentData(StudentDetails sd)
{
SqlConnection db = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\StudentDB.mdf;Integrated Security=True;User Instance=True");
SqlTransaction transaction;
db.Open();
transaction = db.BeginTransaction();
SqlCommand cmd = db.CreateCommand();
try
{
**cmd.CommandText = "insert into StudentDetails(StudentName, DOB, Description, Gender) values ('" + sd.StudentName + "'," +sd.DOB + ",'" + sd.Description + "','" + sd.Gender + "')";
cmd.Transaction = transaction;
cmd.ExecuteNonQuery();**
cmd.CommandText = "select max(StudentID) from StudentDetails";
int id = (int)cmd.ExecuteScalar();
cmd.CommandText = "insert into Qualification (StudentID, Qualification, POY) values ("+id+",'"+sd.Qualification+"',"+sd.POY+")";
cmd.Transaction = transaction;
cmd.ExecuteNonQuery();
transaction.Commit();
}
catch (SqlException sqlError)
{
string s = sqlError.Message.ToString();
transaction.Rollback();
}
db.Close();
return View("SuccessAddStudentData");
}
Thank You
Dilipkumar
Note that date values (DOB) must also contain single quotes.
cmd.CommandText = "insert into StudentDetails(StudentName, DOB, Description, Gender)
values ('" + sd.StudentName + "','" +sd.DOB + "','" +
sd.Description + "','" + sd.Gender + "')";
Also, keep in mind the date format based on SQL Server.
And lastly as other posts mentioned, use bind parameters to prevent SQL injection.
You should ALWAYS use parameterized queries when accessing a SQL database, otherwise your application might be vulnerable to SQL injection. You also should use using when dealing with objects for database access. For example, when the using block is left, the connection will be closed no matter if an exception was thrown or not.
try
{
using (var db = new SqlConnection("connection string"))
using (var transaction = db.BeginTransaction())
using (var cmd = db.CreateCommand())
{
cmd.Transaction = transaction;
db.Open();
cmd.CommandText = "insert into StudentDetails(StudentName, DOB, Description, Gender) values(#name, #dob, #desc, #gender)";
cmd.Parameters.AddWithValue("#name", sd.StudentName);
cmd.Parameters.AddWithValue("#dob", sd.DOB);
cmd.Parameters.AddWithValue("#desc", sd.Description);
cmd.Parameters.AddWithValue("#gender", sd.Gender);
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
// other queries
transaction.Commit();
}
}
catch (SqlException ex)
{
string s = ex.Message.ToString();
}
This code when used in MS-Access is running and updating in property, but when using through database it's giving syntax error
string item = dataGridView1.SelectedRows[0].Cells[0].Value.ToString();
string h="update Follow_Date set Current_Date='" + dateTimePicker1.Value.ToLongDateString() + "', Current_Time='" + dateTimePicker3.Value.ToLongTimeString() + "', Type='" +
comboBox1.SelectedItem.ToString() + "', Remarks='" +
textBox1.Text + "', Next_Follow_Date='" + dateTimePicker2.Value.ToLongDateString()+ "' where Follow_Id='" +
item.ToString() +"'";
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\lernovo\Documents\JDB.mdb");
con.Open();
OleDbCommand cmd = new OleDbCommand(h, con);
cmd.ExecuteNonQuery();
Error is syntax error.
string item = dataGridView1.SelectedRows[0].Cells[0].Value.ToString();
string h="update Follow_Date set #Current_Date, #Current_Time, #Type, #Remarks, #Next_Follow_Date where #Follow_Id";
try
{
Using (OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\lernovo\Documents\JDB.mdb"))
{
con.Open();
Using (OleDbCommand cmd = new OleDbCommand(h, con))
{
cmd.Parameters.Add("Current_Date", dateTimePicker1.Value.ToLongDateString());
cmd.Parameters.Add("Current_Time", dateTimePicker3.Value.ToLongTimeString());
cmd.Parameters.Add("Remarks", textBox1.Text);
cmd.Parameters.Add("Type", comboBox1.SelectedItem.ToString());
cmd.Parameters.Add("Next_Follow_Date", dateTimePicker2.Value.ToLongDateString());
cmd.Parameters.Add("Follow_Id", item.ToString());
cmd.ExecuteNonQuery();
}
}
}
catch(SQLException ex)
{
System.Console.WriteLine(ex.Message, ex.StackaTrace)
}
You're not closing your Database connection and try to use Parameter instead of concatenation(Probe to SQL Injection).
Catch your error message and it trace it using StackTrace. Try to use Using statement to dispose object properly.
Looks like a trivial mistake...
You must have to open the db connection before executing queries on it..
conn=new conn(db param);
try
{
conn.open()
}
catch(Exception e)
{
e.getMessage();
}
I wrote this procedure in a site. it take a string as input parameter(user name) and looks into the related table to find out it's record and return the "ID" field as output of procedure.
this work fine but there's one (major) problem, which is when it take a input in other English language, it can't find the target record and return "-1" as output.
The visitors use Persian language and i observed it in my SQLserver. The collation is "Persian_100_CI_AI" and my string fields are "nvarchar".
what should i do to solve this problem?
i'm using SQL-Server 2008.
thanks a lot
protected int GetThisUserID(string uname)
{
string returnvalue = "";
int returnintegervalue = -1;
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["OldEagleConnectionString"].ToString());
try
{
//SqlCommand command = new SqlCommand("SELECT [ID] FROM [Customers] WHERE ([Uname] = '" + User.Identity.Name.ToString() + "'", connection);
//SqlCommand command = new SqlCommand("SELECT * FROM [Customers] WHERE ([Uname] = '" + User.Identity.Name.ToString() + "')", connection);
SqlCommand command = new SqlCommand("SELECT * FROM [Customers] WHERE ([Uname] = '" + uname + "')", connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
returnvalue = reader["ID"].ToString();
returnintegervalue = Int32.Parse(returnvalue);
}
}
}
catch (SqlException ex)
{
Response.Write(ex.Message.ToString());
returnvalue = ex.Message.ToString();
}
finally
{
connection.Close();
SqlConnection.ClearPool(connection);
}
return returnintegervalue;
}
I hate to answer my own question but here it is:
have to add a N in select command, just like this:
SqlCommand command = new SqlCommand("SELECT * FROM [Customers] WHERE ([Uname] = N'" + uname + "')", connection);
problem solved!
Without the N, the string is taken to be a varchar, and the conversion loses characters outside of that supported by the varchar encoding of the database.