SQL insert syntax, database not updating - c#

EDIT
i changed the code so i am using:[" + Time1 + "] instead of the parameter. This works for the first time, but when the time increases by 0.5, it stays false. The for loop is working as i tried a MessageBox.Show("" + Time1 + ""); inside the for loop.
for (double Time = time_began_5; Time < time_finished_5; Time = Time + 0.5)
{
string Time1 = Time.ToString("0.00");
try
{
SqlConnection cn = new SqlConnection("Data Source=.\\SqlExpress;Initial Catalog=AllensCroft;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFramework;");
cn.Open();
SqlCommand Command = new SqlCommand("INSERT INTO Slots ([Date],[RoomID],[" + Time1 + "]) Values (#date,#room,1)", cn);
Command.Parameters.AddWithValue("date", date);
Command.Parameters.AddWithValue("room", rooms_combo.SelectedValue);
Command.ExecuteNonQuery();
try
{
cn.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

You have a # before your 3rd column (time).
When you add a parameter you need to add the #.
On your insert statement you are trying to insert true as a boolean into the time column.
SqlCommand Command = new SqlCommand("INSERT INTO Slots (Date,RoomID,time) " + "Values (#date,#room,#time)", cn);
Command.Parameters.AddWithValue("#date", date);
Command.Parameters.AddWithValue("#room", rooms_combo.SelectedValue);
Command.Parameters.AddWithValue("#time", Time);
EDIT After comments. Try this:
SqlCommand Command = new SqlCommand("INSERT INTO Slots (Date,RoomID,[" + Time1 + "]) " + "Values (#date,#room,#time)", cn);
Command.Parameters.AddWithValue("#date", date);
Command.Parameters.AddWithValue("#room", rooms_combo.SelectedValue);
Command.Parameters.AddWithValue("#time", true);

You're listing a variable as a column name (#time)
EDIT
Right here:
INSERT INTO Slots (Date, RoomID, --->>> #time <<<--- DANGER WILL ROBINSON, DANGER
To fix it, you need to either change it to a column name from your table, or else get rid of it.
So something like this, for example:
INSERT INTO Slots (Date, RoomID, time)

You can't include a variable in your column list, I presume you wanted that #Time to be in the value list about where that true is.
EDIT: To inject the time as a column name, do some C# string manipulation:
SqlCommand Command = new SqlCommand("INSERT INTO Slots (Date, RoomID, [" + time + "]) Values (#date, #room, 1)", cn);
EDIT again: true is not a T-SQL keyword, T-SQL bit columns have values 1 or 0
Now you don't want to add time as a parameter to the query.

Related

Invalid attempt to call read when reader is closed when inserting data

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.

How to put the autoincrement value in textbox

private void button1_Click(object sender, EventArgs e)
{
String path = "Data Source=LOCALHOST; Initial Catalog= system; username=root; password=''";
MySqlConnection sqlconn = new MySqlConnection(path); //communicator //constructors
MySqlCommand sqlcomm = new MySqlCommand();
sqlconn.Open();
sqlcomm.CommandType = CommandType.Text;
sqlcomm.Connection = sqlconn;
sqlcomm.CommandText = "INSERT INTO maica (Lastname) VALUES ('" + textBox2.Text + "')";
sqlcomm.ExecuteNonQuery();
sqlconn.Close();
MessageBox.Show("Record saved");
}
This is a code in the add button. In phpmyadmin, I checked the autoincrement box. Whenever I run the form, I left the textBox1 which is the ID empty and I input a name in textBox2 which is the Lastname. In phpmyadmin, the ID autoincrements. The textbox1 should have a value of 0001 before I click the add button then after I click the add button, the textBox1 should have 0002. How do I put the autoincrement value in textBox1?This is in winform c#. Sorry for the bad english TIA.
If your database has an ID column with AUTO_INCREMENT set, you do not need to pass a value for the ID into the SQL Insert Statement. You can simply do:
sqlcomm.CommandText = "INSERT INTO maica (Lastname) VALUES ('" + textBox2.Text + ')";
It is also better to use SqlCommand instead of string concatenation as it is protects against SQL Injection and also deals with Type and formatting issues.
That's the query you need to run together with the insert.
SELECT LAST_INSERT_ID();
Here's some code to get the ID, first declare a global String somewhere in the class like that
private String entryIdString;
then
public int insertGetEntryID()
{
String sqlquery = "INSERT INTO maica (Lastname) VALUES ('" + textBox2.Text + "'); SELECT LAST_INSERT_ID();";
SqlCommand command = new SqlCommand(sqlquery, sqlconn);
try
{
sqlconn.Open();
entryIdStr = command.ExecuteScalar().ToString();
return int.Parse(entryIdStr);
}
catch (Exception ex)
{
Console.WriteLine("Exception in DBHandler", ex);
return -1;
}
finally
{
sqlconn.Close();
}
}
This method returns an integer holding the last ID in your table. Now you just set the value to textBox1
textBox1.Text = "ID: " + getEntryID();
or if you want just the ID
textBox1.Text = "" + getEntryID();
I was also just about to tell you what Gideon said about you inserting an ID (when if it's set to autoincrement in the DB, you don't need to).

Incorrect Syntax Error - c#

I am getting an error
Incorrect syntax near '('
I am updating a product from the database when a specific product code is entered.
How can this be done?
// Update product with supplier code entered
DialogResult dr = MessageBox.Show("Are you sure you want to update this product?", "Update Product Details", MessageBoxButtons.YesNo);
if (dr == DialogResult.Yes)
{
try
{
using (SqlConnection SQLcon = new SqlConnection("Data Source = .\\SqlExpress;" + "Initial Catalog=NCAShop;" + "Integrated Security=True;"))
{
SQLcon.Open();
using (SqlCommand addProduct = new SqlCommand("UPDATE dbo.[NCAProduct] (ProductName, SupplierCode, Cost, RetailPrice, Quantity, BestBefore) VALUES ('" + txtUPProductName.Text + "', " + txtUPSupplierCode.Text + ", " + txtUPCost.Text + ", " + txtUPRetail.Text + ", " + txtUPQuantity.Text + ", #date) WHERE ProductCode = " + txtUPProdCode.Text, SQLcon))
{
addProduct.Parameters.Add("#date", SqlDbType.DateTime).Value = bestBeforeDTP.Value.Date;
addProduct.ExecuteNonQuery();
}
}
MessageBox.Show("This product has been successfully added to the database!");
}
catch (Exception error2)
{
MessageBox.Show(error2.ToString());
}
}
else if (dr == DialogResult.No)
{
// Program will continue if user selects 'No'
}
You need to use to correct syntax for an SQL update. The syntax is:
UPDATE table SET column = value, ... WHERE ...
You're mixing it with the INSERT syntax, which is
INSERT INTO Table (Column, ...) VALUES (Value, ...)
I suppose that you actually want to do an INSERT anyway. In that case, replace the word UPDATE in your query with INSERT INTO and you should be fine.
PS: Oh and please - use parameters for all the values, not just the date.
Use proper query formatting sometimes '[ ]' these brackets create an error while executing the query in the DB and please use a proper conversion for specific database types. To prevent sqlinjection attacks I used a SqlCommandParameter for each user provided input. You can use the query given below:
string query = #"UPDATE dbo.[NCAProduct] (
[ProductName],
[SupplierCode],
[Cost],
[RetailPrice],
[Quantity],
[BestBefore]) VALUES
(#txtUPProductName,
#txtUPSupplierCode,
#txtUPCost,
#txtUPRetail,
#txtUPQuantity,
#date)
WHERE [ProductCode] = #txtUPProdCode";
using (SqlCommand addProduct = new SqlCommand(query, SQLcon))
{
addProduct.Parameters.AddWithValue("#date", SqlDbType.DateTime).Value = bestBeforeDTP.Value.Date;
addProduct.Parameters.AddWithValue("#txtUPProductName", txtUPProductName.Text);
addProduct.Parameters.AddWithValue("#txtUPSupplierCode", Convert.ToInt32(txtUPSupplierCode.Text));
addProduct.Parameters.AddWithValue("#txtUPCost", Convert.ToInt32(txtUPCost.Text));
addProduct.Parameters.AddWithValue("#txtUPRetail", Convert.ToInt32(txtUPRetail.Text));
addProduct.Parameters.AddWithValue("#txtUPQuantity", Convert.ToInt32(txtUPQuantity.Text));
addProduct.Parameters.AddWithValue("#txtUPProdCode", Convert.ToInt32(txtUPProdCode.Text));
addProduct.ExecuteNonQuery();
}
Convert text to int64 or double if you are using bigint data type in database.

Getting error when trying to insert a value into a database and get the last inserted id

I am doing a web development in ASP.net with C#.
I am trying to insert some values into the database and get a last inserted id.
This is my code:
int userno2 = Convert.ToInt32(Session["user_id"].ToString());
con = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ConnectionString);
createorder = new SqlDataAdapter("INSERT INTO order (user_id, date) VALUES ('" + userno2 + "', '12-12-2013');select SCOPE_IDENTITY();", con);
order = new DataSet();
createorder.Fill(order, "or_det");
Int32 ord_id = Convert.ToInt32(order.Tables[0].Rows[0]["order_id"].ToString());
When I try to execute the program it gives an error
Incorrect syntax near the keyword 'order'.
Can anyone please help me to fix this error?
order is a reserved word in SQL. If you are using SQL Server, use square brackets to escape it []:
createorder = new SqlDataAdapter("INSERT INTO [order] (user_id, date) VALUES ('" + userno2 + "', '12-12-2013');select SCOPE_IDENTITY();", con);
ORDER is a reserved keyword in T-SQL.
Either don't call your table ORDER, or then you need to "escape" the name with square brackets:
INSERT INTO [order](user_id, date) VALUES ('" + userno2 + "', '12-12-2013');select SCOPE_IDENTITY();", con);
Also: do NOT string together your SQL statement like this! This is highly vulnerable to SQL injection attacks!
Use a parametrized query instead!
INSERT INTO [order](user_id, date) VALUES (#UserId, #Date);
SELECT SCOPE_IDENTITY();
To just insert the row and retrieve the newly inserted ID, I'd personally use a simple SqlCommand and not go the way of using SqlDataAdapter:
string insertStmt = "INSERT INTO [order](user_id, date) VALUES (#UserId, #Date); SELECT SCOPE_IDENTITY();";
using (SqlCommand insertCmd = new SqlCommand(insertStmt, yourSqlConnection))
{
insertCmd.Parameters.Add("#UserID", SqlDbType.Int).Value = xy;
insertCmd.Parameters.Add("#Date", SqlDbType.DateTime).Value = DateTime.Now;
yourSqlConnection.Open();
int newID = (int)insertCmd.ExecuteScalar();
yourSqlConnection.Close();
}
Other than marc_s answer do not use dataset to fetch a single value instead use ExecuteScalar method .
string sql =
"INSERT INTO [order] (user_id, date) VALUES (#user_id, #date); "
+ "SELECT CAST(scope_identity() AS int)";
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand cmd = new SqlCommand(sql , cmd))
{
cmd.Parameters.Add("#user_id", SqlDbType.VarChar);
cmd.Parameters.Add("#date", SqlDbType.DateTime).Value = DateTime.Now;
try
{
conn.Open();
ord_id = (Int32)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

DML query execution from datagridview to SSCE

What I am trying to do:
Execute DML statements into database (SSCE) using Datagridview and command buttons.
The Problem:
I am getting exact same error as this post: SQL [Error]: There was an error parsing the query. [ Token line number = 1,Token line offset = 44,Token in error = - ]
Based on those answers and others available on the web, I have validated the query string, yet not able to solve it. There's also one other aspect I have doubts.
private void button2_Click(object sender, EventArgs e)
{
using (SqlCeConnection CONN = new SqlCeConnection("Data
Source=LocalDBSSCompactEdition.sdf;"))
{
SqlCeCommand comm = new SqlCeCommand();
comm.Connection = CONN;
CONN.Open();
int i = dataGridView2.Rows.Count-1;
String queryString = #"INSERT INTO tblEmployee VALUES ("
+ dataGridView2.Rows[i].Cells["E_ID"].Value + ", "
+ dataGridView2.Rows[i].Cells["FirstName"].Value + ", "
+ dataGridView2.Rows[i].Cells["LastName"].Value + ", "
+ dataGridView2.Rows[i].Cells["DeptID"].Value + ");";
comm.CommandText = queryString;
comm.ExecuteNonQuery();
}
}
1) E_ID column is IDENTITY(auto-increment). However I got an error, saying that I must include all the columns in DataGridview to match to the database table. Could this be the issue that I am getting or could it be my syntax?
2) I want to insert new rows/updates/deleted rows from Datagridview to the database table using a button click event. Is this the efficient way of doing so?
Some insights to the right direction is appreciated.
I managed to get it solved. I don't believe in answering my own-question. Just added the answer hoping for someone else's reference in the future.
1) i variable was referring to an empty row in the datagridview...Hence the values to be inserted were null and these columns are specified NOT NULL...
2) First rule was to follow the usual INSERT statement when ID column is auto-increment. So I specify the columns that I want to insert data for.
3) The data that I was entering were not quoted to treat as String. Fixed.
private void button2_Click(object sender, EventArgs e)
{
using (SqlCeConnection CONN = new SqlCeConnection("Data Source=LocalDBSSCompactEdition.sdf;"))
{
CONN.Open();
SqlCeCommand comm = CONN.CreateCommand();
int i = dataGridView2.Rows.Count-1;
String queryString = #"INSERT INTO tblEmployee (FirstName, LastName, DeptID) VALUES ('"
+ dataGridView2.Rows[5].Cells["FirstName"].Value + "','"
+ dataGridView2.Rows[5].Cells["LastName"].Value + "',"
+ dataGridView2.Rows[5].Cells["DeptID"].Value + ");";
comm.CommandText = queryString;
comm.ExecuteNonQuery();
CONN.Close();
}
}

Categories