Use a while loop to insert into table - c#

I'm trying to use a while loop to insert into a table from a List. I want to loop through and write each item from the list by it's index. I'm getting an error with the values I'm trying to insert.
"SQL logic error or missing database near "[y]": syntax error"
while (y < Name.Count)
{
cmd.CommandText = "INSERT INTO Mytable(Column1,Column2) values(Column1[y], Column2[y])";
cmd.ExecuteNonQuery();
y++;
}

Your query is not correct. You need to pass parameters to the query:
"INSERT INTO Mytable(Column1,Column2) values(Column1[#Column1], Column2[#Column1])"
command.Parameters.Add( new SqlParameter( "#Column1", y ) );
Having said that, if I were you, I would use Bulk Insert (or something similar) for this and transfer all the data to the database in one trip.

Your parameters, Column1[y] and Column2[y], are not handled as a index to a data structure but rather as plain text.
cmd.CommandText = "INSERT INTO Mytable(Column1,Column2) values(" + Column1[y] + ", " + Column2[y] + ")";

Related

C# insert combo box item index in small int column

I want to insert the selected item index from a combobox into a tinyint column (FoodType) in SQL Server. I wrote the code below, but I get an exception:
Must declare the scalar variable #fType
What must I do?
string query = "INSERT INTO MenuTbl (FoodName,FoodType,FoodUnit, SalePrice)" +
"VALUES (#fName, #fType, #fUnit, #fPrice)";
connection = new SqlConnection(conectionString);
SqlCommand cmd = new SqlCommand(query,connection);
cmd.Parameters.AddWithValue("#fName", FNameTextBox.Text.Trim());
cmd.Parameters.AddWithValue("#fTyp", TypeComboBox.SelectedIndex + 1);
cmd.Parameters.AddWithValue("#funit", UnitComboBox.SelectedIndex +1);
cmd.Parameters.AddWithValue("#fprice", int.Parse(PriceEdit.Text));
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
Are you missing an "e" on the parameter?
cmd.Parameters.AddWithValue("#fTyp", TypeComboBox.SelectedIndex + 1);
I think you made a typo with this line of code
cmd.Parameters.AddWithValue("#fTyp", TypeComboBox.SelectedIndex + 1);
It should be #fType atleast according to your select query
string query = "Insert into MenuTbl (FoodName,FoodType,FoodUnit, SalePrice)" +
"VALUES (#fName,#fType,#fUnit, #fPrice)";
And I also think that TypeComboBox.SelectedIndex + 1 will only give you the index+1 numerical value rather than the selected text contents. Is that what you want?

How do I make a foreign key in one of my databases copy the primary key that it is referencing to while I create a record? [duplicate]

I have a query to insert a row into a table, which has a field called ID, which is populated using an AUTO_INCREMENT on the column. I need to get this value for the next bit of functionality, but when I run the following, it always returns 0 even though the actual value is not 0:
MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertInvoice;
comm.CommandText += "\'" + invoiceDate.ToString("yyyy:MM:dd hh:mm:ss") + "\', " + bookFee + ", " + adminFee + ", " + totalFee + ", " + customerID + ")";
int id = Convert.ToInt32(comm.ExecuteScalar());
According to my understanding, this should return the ID column, but it just returns 0 every time. Any ideas?
EDIT:
When I run:
"INSERT INTO INVOICE (INVOICE_DATE, BOOK_FEE, ADMIN_FEE, TOTAL_FEE, CUSTOMER_ID) VALUES ('2009:01:01 10:21:12', 50, 7, 57, 2134);last_insert_id();"
I get:
{"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 'last_insert_id()' at line 1"}
MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertStatement; // Set the insert statement
comm.ExecuteNonQuery(); // Execute the command
long id = comm.LastInsertedId; // Get the ID of the inserted item
[Edit: added "select" before references to last_insert_id()]
What about running "select last_insert_id();" after your insert?
MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertInvoice;
comm.CommandText += "\'" + invoiceDate.ToString("yyyy:MM:dd hh:mm:ss") + "\', "
+ bookFee + ", " + adminFee + ", " + totalFee + ", " + customerID + ");";
+ "select last_insert_id();"
int id = Convert.ToInt32(comm.ExecuteScalar());
Edit: As duffymo mentioned, you really would be well served using parameterized queries like this.
Edit: Until you switch over to a parameterized version, you might find peace with string.Format:
comm.CommandText = string.Format("{0} '{1}', {2}, {3}, {4}, {5}); select last_insert_id();",
insertInvoice, invoiceDate.ToString(...), bookFee, adminFee, totalFee, customerID);
Use LastInsertedId.
View my suggestion with example here: http://livshitz.wordpress.com/2011/10/28/returning-last-inserted-id-in-c-using-mysql-db-provider/
It bothers me to see anybody taking a Date and storing it in a database as a String. Why not have the column type reflect reality?
I'm also surprised to see a SQL query being built up using string concatenation. I'm a Java developer, and I don't know C# at all, but I'd wonder if there wasn't a binding mechanism along the lines of java.sql.PreparedStatement somewhere in the library? It's recommended for guarding against SQL injection attacks. Another benefit is possible performance benefits, because the SQL can be parsed, verified, cached once, and reused.
Actually, the ExecuteScalar method returns the first column of the first row of the DataSet being returned. In your case, you're only doing an Insert, you're not actually querying any data. You need to query the scope_identity() after you're insert (that's the syntax for SQL Server) and then you'll have your answer. See here:
Linkage
EDIT: As Michael Haren pointed out, you mentioned in your tag you're using MySql, use last_insert_id(); instead of scope_identity();

I have inserted a row, I want to get it's ID and plus it with an int and insert in that row

I have inserted a row into my table, and I want to get it's ID and plus it with an int and inserted in that row.
But I don't know how to get it's ID.
Here is the insert code:
objCommand.Connection = objConnection;
objCommand.CommandText = "INSERT INTO Moin " +
" (Title, TotalID, Code ) " +
"VALUES (#Title , #TotalID, #Code )";
objCommand.Connection = objConnection;
objCommand.CommandText = "INSERT INTO Moin " +
" (Title, TotalID, Code ) " +
"VALUES (#Title , #TotalID, #Code ) SELECT SCOPE_IDENTITY()";
object id = objCommand.ExecuteScalar();
Try using the OUTPUT clause of SQL Server in your query - it can return any of the just inserted value (here I'm assuming your column is called ID - adapt as needed):
objCommand.Connection = objConnection;
objCommand.CommandText = "INSERT INTO Moin(Title, TotalID, Code ) " +
"OUTPUT Inserted.ID " +
"VALUES (#Title , #TotalID, #Code ); "
and then execute it like this:
int result = (int)objCommand.ExecuteScalar();
Since you're returning just one row and one column (just the INT), you can use .ExecuteScalar() to retrieve that value back from the INSERT statement.
With the OUTPUT clause, you can return any values just inserted - not just the identity column. So you could also return values that are filled by the database with default values, or whatever you need. If you return multiple values, you need to use a data reader to read them all - ExecuteScalar() only works for a single value.
But, as Anders correctly mentioned - using an ORM like Entity Framework would do all of this automatically for you and you wouldn't have to deal with those raw SQL commands anymore....
Building SQL commands in strings should be considered a legacy technique. If you use Entity Framework or linq-to-sql the retrieval of the id is handled automatically for you.
With pure SQL, use the SCOPE_IDENTITY() function to retrieve the id of the inserted element.

asp.net SQL Server insert statement tidyup + error

I have a form which inserts data into a database.
There are certain fields that are not always going to be needed.
When I leave these blank in my code I get a error saying.
Column name or number of supplied values does not match table
definition.
This is how I have the database setup. SQL Server 2008
[youthclubid]
[youthclubname]
[description]
[address1]
[address2]
[county]
[postcode]
[email]
[phone]
Here is the code that I have connecting to the database and doing the insert.
connection.Open();
cmd = new SqlCommand("insert into youthclublist values ('" + youthclubname.Text + "', '" + description.Text + "','" + address1.Text + "','" + address2.Text + "', '" + county.Text + "', '" + postcode.Text + "', '" + email.Text + "', '" + phone.Text + "')", connection);
cmd.ExecuteNonQuery();
You have two major problems:
1) concatenating together your SQL statement is prone to SQL injection attacks - don't do it, use parametrized queries instead
2) You're not defining which columns you want to insert in your table - by default, that'll be all columns, and if you don't provide values for all of them, you'll get that error you're seeing.
My recommendation: always use a parametrized query and explicitly define your columns in the INSERT statement. That way, you can define which parameters to have values and which don't, and you're safe from injection attacks - and your performance will be better, too!
string insertStmt =
"INSERT INTO dbo.YouthClubList(Youthclubname, [Description], " +
"address1, address2, county, postcode, email, phone) " +
"VALUES(#Youthclubname, #Description, " +
"#address1, #address2, #county, #postcode, #email, #phone)";
using(SqlConnection connection = new SqlConnection(.....))
using(SqlCommand cmdInsert = new SqlCommand(insertStmt, connection))
{
// set up parameters
cmdInsert.Parameters.Add("#YouthClubName", SqlDbType.VarChar, 100);
cmdInsert.Parameters.Add("#Description", SqlDbType.VarChar, 100);
.... and so on
// set values - set those parameters that you want to insert, leave others empty
cmdInsert.Parameters["#YouthClubName"].Value = .......;
connection.Open();
cmdInsert.ExecuteNonQuery();
connection.Close();
}
The first major issue is that you are concatenating inputs in the query. This makes your application highly vulnerable to SQL Injection. Do not do this. Use a parametrized query.
The regular syntax for insert statement is like this:
Insert into <TableName> (Col1, Col2...Coln) values (val1, val2...valn)
If you need to insert only a selected set of columns, you need to provide the list of columns you are inserting data into in the column list.
If you do not specify the column list, the indication is that you are inserting data to each one of them.
So you may check for the input and if it is not there, you may omit the respective column.
The other better way is use a stored proc. That will ease out the issue.
This not way to do the code you make use of SqlParameter for this kind of statement.
So your code something like
SqlConnection thisConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Northwind_ConnectionString"].ConnectionString);
//Create Command object
SqlCommand nonqueryCommand = thisConnection.CreateCommand();
try
{
// Create INSERT statement with named parameters
nonqueryCommand.CommandText = "INSERT INTO Employees (FirstName, LastName) VALUES (#FirstName, #LastName)";
// Add Parameters to Command Parameters collection
nonqueryCommand.Parameters.Add("#FirstName", SqlDbType.VarChar, 10);
nonqueryCommand.Parameters.Add("#LastName", SqlDbType.VarChar, 20);
nonqueryCommand.Parameters["#FirstName"].Value = txtFirstName.Text;
nonqueryCommand.Parameters["#LastName"].Value = txtLastName.Text;
// Open Connection
thisConnection.Open();
nonqueryCommand.ExecuteNonQuery();
}
catch (SqlException ex)
{
// Display error
lblErrMsg.Text = ex.ToString();
lblErrMsg.Visible = true;
}
finally
{
// Close Connection
thisConnection.Close();
}
You need to tell SQL server that which field you want to insert like
insert into youthclublist(youthclubid, youthclubname, ....) values ('" + youthclubname.Text + "', '" + description.Text + "'.....
and you are fine.
Though new into programming, the easiest way i know to insert into a database is to create a "save" stored procedure, which is then called up through your connection string. Believe me, this is the best way.
Another way around is to use LINQ to SQL. i found this much more easier. Follow this steps.
Add a new LINQ to SQL Classes to your project. Make sure the file extension is '.dbml'. Name it your name of choice say "YouthClub.dbml"
Connect your Database to Visual Studio using the Server Explorer
Drag your table to the OR Designer.(I'm not allowed to post images).
You can now save to the Database with this code
//Create a new DataContext
YouthClubDataContext db = new YouthClubDataContext();
//Create a new Object to be submitted
YouthClubTable newYouthClubRecord = new YouthClubTable();
newYouthClubRecord.youthlubname = txtyouthclubname.Text;
newYouthClubRecord.description = txtdescription.Text;
newYouthClubRecord.address1 = txtaddress1.Text;
newYouthClubRecord.address2 = txtaddress2.Text;
newYouthClubRecord.county = txtcounty.Text;
newYouthClubRecord.email = txtemail.Text;
newYouthClubRecord.phone = txtphone.Text;
newYouthClubRecord.postcode = txtpostcode.Text;
//Submit to the Database
db.YouthClubTables.InsertOnSubmit(newYouthClubRecord);
db.SubmitChanges();
Hope this time I have given a real answer

Getting SQLException when debugging

I've got a error which I can't understand. When I'm debugging and trying to run a insert statement, its throwing the following exception:
"There are fewer columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement."
I have looked all over my code, and I can't find the mistake I've made.
This is the query and the surrounding code:
SqlConnection myCon = DBcon.getInstance().conn();
int id = gm.GetID("SELECT ListID from Indkøbsliste");
id++;
Console.WriteLine("LNr: " + listnr);
string streg = GetStregkode(navne);
Console.WriteLine("stregk :" + strege);
string navn = GetVareNavn(strege);
Console.WriteLine("navn :" + navne);
myCon.Open();
string query = "INSERT INTO Indkøbsliste (ListID, ListeNr, Stregkode, Navn, Antal, Pris) Values(" + id + "," + listnr + ", '" + strege + "','" + navn + "'," + il.Antal + ", "+il.Pris+")";
Console.WriteLine(il.Antal+" Antal");
Console.WriteLine(il.Pris+" Pris");
Console.WriteLine(id + " ID");
SqlCommand com = new SqlCommand(query, myCon);
com.ExecuteNonQuery();
com.Dispose();
myCon.Close();
First of all check the connection string and confirm the database location and number of columns a table has.
Suggestion : Do not use hardcoded SQL string. Use parameterized sql statements or stored-proc.
Try parameterized way,
string query = "INSERT INTO Indkøbsliste (ListID, ListeNr, Stregkode, Navn, Antal, Pris)
Values (#ListID, #ListeNr, #Stregkode, #Navn, #Antal, #Pris)"
SqlCommand com = new SqlCommand(query, myCon);
com.Parameters.Add("#ListID",System.Data.SqlDbType.Int).Value=id;
com.Parameters.Add("#ListeNr",System.Data.SqlDbType.Int).Value=listnr;
com.Parameters.Add("#Stregkode",System.Data.SqlDbType.VarChar).Value=strege ;
com.Parameters.Add("#Navn",System.Data.SqlDbType.VarChar).Value=navn ;
com.Parameters.Add("#Antal",System.Data.SqlDbType.Int).Value=il.Antal;
com.Parameters.Add("#Pris",System.Data.SqlDbType.Int).Value=il.Pris;
com.ExecuteNonQuery();
Please always use parametrized queries. This helps with errors like the one you have, and far more important protects against SQL injection (google the term, or check this blog entry - as an example).
For example, what are the actual values of strege and/or navn. Depending on that it may render your SQL statement syntactically invalid or do something worse.
It (looks like) a little more work in the beginning, but will pay off big time in the end.
Are you using danish culture settings?
In that case if il.Pris is a double or decimal it will be printed using comma, which means that your sql will have an extra comma.
Ie:
INSERT INTO Indkøbsliste (ListID, ListeNr, Stregkode, Navn, Antal, Pris) Values(33,5566, 'stegkode','somename',4, 99,44)
where 99,44 is the price.
The solution is to use parameters instead of using the values directly in you sql. See some of the other answers already explaining this.

Categories