I have a table which is needed to be updated from a windows form, i am able to update the displayed values into the table where as i am unable to update a particular column where the value to be updated must be a reference value of the displayed data on windows form. The reference value is in another table. Following is the code:
command.CommandText = "INSERT INTO tblComplaints (ComplaintID, Description,ComplaintTypeID,ReceivedDate,ComplaintTypeID)VALUES('" + TextBox7.Text + "','" + TextBox10.Text + "','" + dateTimePicker1.Text + "',???)";
The question mark(???) within the code is what I require.
To be more precise ComplaintTypeName is being displayed in the form in comboBox1 whereas I require its ID to be updated whose values are present in tblComplaintType
Assuming you assigned the ComboBox values somehow like this in advance
ComboboxItem item = new ComboboxItem();
item.Text = "Item text1";
item.Value = 12;
comboBox1.Items.Add(item);
you could do the following:
command.CommandText = "INSERT INTO tblComplaints " +
"(ComplaintID, Description, ComplaintTypeID, ReceivedDate, ComplaintTypeID) " +
"VALUES (#Description,#ComplaintTypeID,#ReceivedDate,#ComplaintTypeID)";
command.Parameters.AddWithValue("#Description", TextBox7.Text);
command.Parameters.AddWithValue("#ComplaintTypeID", TextBox10.Text);
command.Parameters.AddWithValue("#ReceivedDate", dateTimePicker1.Text);
command.Parameters.AddWithValue("#ComplaintTypeID", comboBox1.SelectedValue);
Note that I stripped the ComplaintID from the sql command. Since this is a INSERT statement, you're likely to get a generated ID for that record. If that's not the case you'll have to provide another parameter in the command.
Additionally you should always parameterize your commands instead of building them via string concatenation to prevent sql injection.
Related
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 made a Table using a Database in visual 2015 and in the table I have name, n1 , n2 , and avg. I made a insert button with 3 textboxes where I insert my name, number1 and number2 and when I press the button I want to save them in a table. If I use 4 textboxes (one for avg) it works, but I want to use a trigger. So.. I created a trigger >
CREATE TRIGGER [Trigger]
ON [dbo].[Table1]
FOR DELETE, INSERT, UPDATE
AS
BEGIN
UPDATE Table1
SET avg = (N1+N2)/2
END
and here is my insert string
string ins = "insert into Table1 values ('"; ins += textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "')";
and I get this error..
Column name or number of supplied values does not match table definition.
I don't know what to do :(
Ok, I still don't think we have all the information, but I'll give a crack at it...
The error message is from the insert statement, not from the trigger.
For your insert, I'd format it so you specifically state which values/columns will be inserted into the table.
It appears as though your average column is a non-nullable field, without a default constraint. So when you try to insert just the 3 values, it wants 4, because it HAS to have 4 (non-nullable). That's why it's throwing the error.
I'd structure your isnert like this:
insert
into Table (Col1, Col2, Col3)
values (val1, val2, val3)
Then, add a default constraint [then updated by trigger], OR, make the Average column nullable, so it can again then be updated via the trigger.
I bet you have a primary key column or another column you're not telling us about.
Either make the Primary Key column Auto-Increment, or make each column allow nulls or give each column a default value.
Also look up SQL Injection as your insert statement is susceptible to attacks.
There is also a problem with your syntax:
string ins = "insert into Table1 values ('"; ins += textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "')";
It should be
string ins = "insert into Table1 values ('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "')";
I am using a foreach loop to access the values of objects(of type Meal) stored in a list. Then I am calling a database query to save these values into the database .
This is the code I'm using :
foreach (Meal ml in mVals)
{
mID = ml.mealID;
MessageBox.Show(Convert.ToString(mID));
string oString2 = " INSERT into [dbo].[OrderMeal] (orderId,mealId,quantity) " + " VALUES ('" + orderId + "','" + mID + "','" + Convert.ToInt32(quant.Text) + "') ;";
SqlCommand oCmd2 = new SqlCommand(oString2, myConnection);
oCmd2.ExecuteNonQuery();
}
However, this only works for the last value in the list. The next loop iteration seems to be doing the same function, thereby saving the same record, giving an
error of violating the primary key constraint .
Is there some error in the way I am looping through the List?
What the structure of OrderMeal table?
Probably you have primary key in your table, and you need to vetify that you don't duplicate him.
try to enter the value in the list from the sql management.
verify that you don't have special characters in each item in the list( like comma and Apostrophe).
I think you can concatenate a set of insert statement and then ExcuteNonQuery for better performance.
I use the following code to insert a record from one database to another but it doesn't work. I tried the query in MS-ACCESS 2007 and it works fine but it doesn't work when called programmatically from my C# code?
string query_insert = "INSERT INTO Questionnaires_Table(BranchName,Factor,Region,Branch_ID,Current_Date,No_Employees) "
+ "SELECT BranchName,Factor,Region,Branch_ID,Current_Date,No_Employees "
+ "FROM Questionnaires_Table IN '" + dialog.FileName + "' Where Branch_ID = " + textBox1.Text ;
dbConnDest.Open();
OleDbDataAdapter dAdapter = new OleDbDataAdapter();
OleDbCommand cmd_insert = new OleDbCommand(query_insert, dbConnDest);
dAdapter.InsertCommand = cmd_insert;
textBox2.Text = query_insert.ToString();
dbConnDest.Close();
When I take the the content of query_insert in ms access, it works fine.
I think you need to use
cmd_insert.executeNonQuery()
Remove the comma after the last field name in the SELECT list.
"SELECT BranchName,Factor,Region,Branch_ID,Current_Date,No_Employees"
dAdapter.Update();
should do the trick
This seems suspect:
" Where Branch_ID = " + textBox1.Text ;
Does textBox1 contain a numeric ID? Does the ID that is entered exist in the source database?
I would 1) do a check that the ID exists and warn the user if it doesn't, and 2) change the query to use paramters instead of concatenating SQL.
What would happen if your company opened a branch with the ID of
"1; DROP TABLE Branches"
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