SqlCeCommand Parameters not working - c#

I have a SQL Server Compact database and I'm trying to insert a record into it using cmd.ExecuteNonQuery(). This method worked perfectly fine in another project, but it doesn't work now.
private void AddNewProfile() {
try {
using(SqlCeConnection conn = new SqlCeConnection(Properties.Settings.Default.dbConnectionString)) {
using(SqlCeCommand cmd = new SqlCeCommand()) {
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription) VALUES ('#name', '#path', '#desc');";
cmd.Parameters.AddWithValue("#name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.AddWithValue("#path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.AddWithValue("#desc", SqlDbType.Text).Value = "A blank profile.";
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
}
catch(Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}
The problem comes in with the parameters - I practically copied the code from one of my other projects, but it doesn't work correctly. Instead of executing this:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES ('New Profile', 'C:\\', 'A blank profile.');
it executes this:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES ('#name', '#path', '#desc');
What is the problem here?

Two problems:
Firstly, your SQL is specifying literal values because of the quotes. It should be:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES (#name, #path, #desc)
That way the SQL refers to the parameters, rather than literals with values of `"#name", "#path" and "#desc".
(I've removed the unnecessary semi-colon as well.)
Secondly, calling AddWithValue, but providing the type as the value, then overwriting the value. That's pointless and confusing - the type you're specifying is going to be lost. You should be using:
cmd.Parameters.Add("#name", SqlDbType.Text).Value = "New Profile";
Finally, you don't need to call conn.Close() - it's already in a using statement... and you can pass conn to the SqlCeCommand constructor, to make things slightly simpler.

You don't need to use single quotes when you declare your parameters. With single quotes, SQL will recognize them as a string literal not parameters. Just use them in your SqlCommand like;
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES (#name, #path, #desc)
Also you are using AddWithValue in a wrong way. It doesn't need the type.
cmd.Parameters.AddWithValue("#name", "New Profile");
cmd.Parameters.AddWithValue("#path", "C:\\");
cmd.Parameters.AddWithValue("#desc", "A blank profile.");
or you can use Add if you want to declare their types like;
cmd.Parameters.Add("#name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.Add("#path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.Add("#desc", SqlDbType.Text).Value = "A blank profile.");
And your conn.Close(); is redundant. The using statement will take care of it for you. Under the hood, SqlConnection.Dispose() calls the SqlConnection.Close() method.

Problem 1: You are enclosig the parameters (#name, #path, #desc) within single quotes, so that you are passing the values as #name, #path, #desc .
Solution 1: You should not enclose the Parameters within single quotes while using Parameterised queries.
Replace This:
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath,
ProfileDescription) VALUES ('#name', '#path', '#desc');";
With This:
cmd.CommandText = "INSERT INTO Profiles
(ProfileName, ProfilePath, ProfileDescription)
VALUES (#name, #path, #desc);";
Problem 2: you need to provide both parameter name and its value to the Parameters.AddWithValue() method
Solution 2:
Replace This:
cmd.Parameters.AddWithValue("#name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.AddWithValue("#path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.AddWithValue("#desc", SqlDbType.Text).Value = "A blank profile.";
With This:
cmd.Parameters.AddWithValue("#name","New Profile");
cmd.Parameters.AddWithValue("#path","C:\\");
cmd.Parameters.AddWithValue("#desc","A blank profile.");
Complete Code:
private void AddNewProfile() {
try {
using(SqlCeConnection conn = new SqlCeConnection(Properties.Settings.Default.dbConnectionString)) {
using(SqlCeCommand cmd = new SqlCeCommand()) {
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath,
ProfileDescription) VALUES (#name,#path, #desc);";
cmd.Parameters.AddWithValue("#name","New Profile");
cmd.Parameters.AddWithValue("#path","C:\\");
cmd.Parameters.AddWithValue("#desc","A blank profile.");
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
catch(Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}

Related

Combining Two SQL Queries - ASP.NET

I have two SQL queries:
SqlCommand cmdone = new SqlCommand("update HardwareDetails Set Transstat = #Transstat where AssetNo = #AssetNo", con);
cmdone.Parameters.AddWithValue(#"Transstat", "Raised");
cmdone.Parameters.AddWithValue(#"AssetNo", txtAsset.Text);
cmdone.ExecuteNonQuery();
cmdone.Dispose();
And:
SqlCommand cmd = new SqlCommand("Insert into TransferRequest(FrmName,FrmEmpId,ToName) values (#FrmName,#FrmEmpId,#ToName", con);
cmd.Parameters.AddWithValue(#"FrmName", txtfrm.Text);
cmd.Parameters.AddWithValue(#"FrmEmpId", Global.transferorid);
cmd.Parameters.AddWithValue(#"ToName", txtName.Text);
cmd.ExecuteNonQuery();
cmd.Dispose();
Is there a way to combine them into a single query?
Put a semi-colon between the two SQL statements, and add all the parameters.
using (SqlCommand cmd = new SqlCommand("UPDATE HardwareDetails SET Transstat = #Transstat WHERE AssetNo = AssetNo; INSERT INTO TransferRequest (FrmName, FrmEmpId, ToName) VALUES (#FrmName, #FrmEmpId, #ToName)", con))
{
cmd.Parameters.AddWithValue(#"Transstat", "Raised");
cmd.Parameters.AddWithValue(#"AssetNo", txtAsset.Text);
cmd.Parameters.AddWithValue(#"FrmName", txtfrm.Text);
cmd.Parameters.AddWithValue(#"FrmEmpId", Global.transferorid);
cmd.Parameters.AddWithValue(#"ToName", txtName.Text);
cmd.ExecuteNonQuery();
}
Comments:
Its best practice (because its safer) to create your cmd within a using block.
AddWithValue should not be used, instead create the SqlParameter using its constructor and specify the type and precision. E.g. cmd.Parameters.Add(new SqlParameter("#Transstat", SqlDataType.VarChar, 6) { Value = "Raised"});
As pointed out by Liam as it stands this does break the Single Responsibility Principle. Personally I would only use this method if the two statements are linked/related in some way.
string query = #"
update HardwareDetails Set Transstat = #Transstat where AssetNo = #AssetNo
Insert into TransferRequest(FrmName,FrmEmpId,ToName) values (#FrmName,#FrmEmpId,#ToName)";
SqlCommand cmd= new SqlCommand(query,con);
cmd.Parameters.AddWithValue(#"Transstat", "Raised");
cmd.Parameters.AddWithValue(#"AssetNo", txtAsset.Text);
cmd.Parameters.AddWithValue(#"FrmName", txtfrm.Text);
cmd.Parameters.AddWithValue(#"FrmEmpId", Global.transferorid);
cmd.Parameters.AddWithValue(#"ToName", txtName.Text);
cmd.ExecuteNonQuery();
cmd.Dispose();

Incorrect syntax near',',

I am trying to add data into a database. When I run code in the save button method, the above error pops up.
try
{
string constr = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\Noah\Desktop\vs13\Project\JW_Accounting_Appliction\JW_Accounting_App\myDatabase.mdf;Integrated Security=True";
SqlConnection conn = new SqlConnection(constr); //connects to regstration DB//
conn.Open(); //to open connection to DB
String insertQuery = "insert into AccountReceipt(TNo.,[Date], [WorldWide], [Local], [sumWW_Local]) values (#TNo., #Date, #WorldWide, #Local, #sumWW_Local)"; // inserts into table and declares data as variables//
SqlCommand com = new SqlCommand(insertQuery, conn);
com.Parameters.AddWithValue("#TNo.", textBox1.Text);
com.Parameters.AddWithValue("#Date", pickerDate.Text);
com.Parameters.AddWithValue("#WorldWide", txtWorldWide.Text);
com.Parameters.AddWithValue("#Local", txtLocal.Text);
com.Parameters.AddWithValue("#sumWW_Local", txtTotal.Text);
com.ExecuteNonQuery();
MessageBox.Show("Thank you, Your registration has been successfull!");
conn.Close();
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
The usage of parameterization is appreciated, But you have to care about naming conventions as well. Here the issue is with the column name TNo. please enclose then inside a [] ie.,
"insert into AccountReceipt([TNo.] .. // rest of codce)
Anyway TNo. would not be a good name for a column, try to follow some good naming conventions
Don't use No. both in column name and in paramater.
insert into AccountReceipt([TNo.],[Date], [WorldWide], [Local], [sumWW_Local]) values (#TNo, #Date, #WorldWide, #Local, #sumWW_Local)
com.Parameters.AddWithValue("#TNo", textBox1.Text);

Excel to DataTable Insert

I am trying to insert into a database from Excel, and I've got all values from Excel. When I insert into my database I get Factal Exception. How do I recover from this exception?
MySqlCommand commd = new MySqlCommand();
commd.Connection = OpenConnection();
commd.CommandText = "INSERT INTO sqa_tracking(IID,STARTDATE,ENDDATE,WEEK,SUPPLIER,LINENO,ORDER_ID,BRCARID,PAGE_FIRST,PAGE_LAST,PAGE_COUNT,ARTICLE_NO,COUNT_LINENO,TOTAL_NR_OF_ITEMS,CAR_SUPPLIER,CONTENT_PROVIDER_NAME,MANIFESTATION,FACTOR,UNITS,DATE_OF_SUBMISSION,UNITS_KEY,COUNT_UNITS_KEY,TOTAL_NR_OF_UNITS,ERRORS,KPI_ERRORS,OBII_ELEMENT,CAR_FIELD_NAME,ERROR_TYPE,WRONG_CAPTURE_IN_FILE,CORRECT_CAPTURE_WOULD_BE,REPEATING_IN_CAR,SOURCE_FILE_TYPE,FULL_AUTOM_CONV,ERROR_IN_SOURCE_FILE,ROOT_CAUSE_OF_THE_ERROR,PREVENTIVE_MEASURES,DATE_OF_IMPLEMENTATION,DATE_OF_TRANSMISSION,VALIDATED) VALUES (#IID,#STARTDATE,#ENDDATE,#WEEK,#SUPPLIER,#LINENO,#ORDER_ID,#BRCARID,#PAGE_FIRST,#PAGE_LAST,#PAGE_COUNT,#ARTICLE_NO,#COUNT_LINENO,#TOTAL_NR_OF_ITEMS,#CAR_SUPPLIER,#CONTENT_PROVIDER_NAME,#MANIFESTATION,#FACTOR,#UNITS,#DATE_OF_SUBMISSION,#UNITS_KEY,#COUNT_UNITS_KEY,#TOTAL_NR_OF_UNITS,#ERRORS,#KPI_ERRORS,#OBII_ELEMENT,#CAR_FIELD_NAME,#ERROR_TYPE,#WRONG_CAPTURE_IN_FILE,#CORRECT_CAPTURE_WOULD_BE,#REPEATING_IN_CAR,#SOURCE_FILE_TYPE,#FULL_AUTOM_CONV,#ERROR_IN_SOURCE_FILE,#ROOT_CAUSE_OF_THE_ERROR,#PREVENTIVE_MEASURES,#DATE_OF_IMPLEMENTATION,#DATE_OF_SUBMISSION,#VALIDATED) ";
commd.Parameters.AddWithValue("#STARTDATE", StartDate);
commd.Parameters.AddWithValue("#ENDDATE", EndDate);
commd.Parameters.AddWithValue("#WEEK", Week);
commd.Parameters.AddWithValue("#SUPPLIER", Supplier);
commd.Parameters.AddWithValue("#LINENO", LineNo);
commd.Parameters.AddWithValue("#ORDER_ID", ORDERID);
commd.Parameters.AddWithValue("#BRCARID", "");
commd.Parameters.AddWithValue("#PAGE_FIRST", PageFirst);
commd.Parameters.AddWithValue("#PAGE_LAST", Pagelast);
commd.Parameters.AddWithValue("#PAGE_COUNT", Pagecount);
commd.Parameters.AddWithValue("#ARTICLE_NO", ArticleNo);
commd.Parameters.AddWithValue("#COUNT_LINENO", COUNTLineNo);
commd.Parameters.AddWithValue("#TOTAL_NR_OF_ITEMS", Totalnrofitems);
commd.Parameters.AddWithValue("#CAR_SUPPLIER", CARSupplier);
commd.Parameters.AddWithValue("#CONTENT_PROVIDER_NAME", ContentProvidename);
commd.Parameters.AddWithValue("#MANIFESTATION", Manifestation);
commd.Parameters.AddWithValue("#FACTOR", AU);
commd.Parameters.AddWithValue("#UNITS", Units);
commd.Parameters.AddWithValue("#DATE_OF_SUBMISSION", Dateoftransmission);
commd.Parameters.AddWithValue("#UNITS_KEY", unitskey);
commd.Parameters.AddWithValue("#COUNT_UNITS_KEY", COUNTunitskey);
commd.Parameters.AddWithValue("ERRORS", Errors);
commd.Parameters.AddWithValue("#KPI_ERRORS", KPIErrors);
commd.Parameters.AddWithValue("#OBII_ELEMENT", OBIIElement);
commd.Parameters.AddWithValue("#CAR_FIELD_NAME", CARFieldname);
commd.Parameters.AddWithValue("#ERROR_TYPE", Errortype);
commd.Parameters.AddWithValue("#IID", IID);
commd.Parameters.AddWithValue("#WRONG_CAPTURE_IN_FILE", Wrongcaptureinfile);
commd.Parameters.AddWithValue("#CORRECT_CAPTURE_WOULD_BE", Correctcapturewouldbe);
commd.Parameters.AddWithValue("#REPEATING_IN_CAR", RepeatinginCAR);
commd.Parameters.AddWithValue("#SOURCE_FILE_TYPE", Sourcefiletype);
commd.Parameters.AddWithValue("#FULL_AUTOM_CONV", FulAutomConv);
commd.Parameters.AddWithValue("#ERROR_IN_SOURCE_FILE", Errorinsourcefile);
commd.Parameters.AddWithValue("#ROOT_CAUSE_OF_THE_ERROR", RootCauseoftheError);
commd.Parameters.AddWithValue("#PREVENTIVE_MEASURES", PreventiveMeasures);
commd.Parameters.AddWithValue("#DATE_OF_IMPLEMENTATION", DateofImplementation);
commd.Parameters.AddWithValue("#VALIDATED", Validated);
commd.ExecuteNonQuery();`
I used inline query and I got the parameter values from DataTable.
Always remember that fatal error occurred during command execution only because of incorrect parameters value name.
so correct the parameter value to avoid fetal errors during command execution
You have not provided parameter value for TOTAL_NR_OF_UNITS & DATE_OF_TRANSMISSION.
Also Please follow the order in your insert query and while adding parameters, makes it easier to troubleshoot.
commd.Parameters.AddWithValue("#TOTAL_NR_OF_UNITS",TotalNrOfUnits);
commd.Parameters.AddWithValue("#DATE_OF_TRANSMISSION", DateOfTransmission);
Either this . . .
SqlCommand cmd = new SqlCommand("insert into tbl_insert values (#id,#name,#Email,#City)");
cmd.Parameters.AddWithValue("#id", Convert.ToInt32(txtId.Text));
cmd.Parameters.AddWithValue("#name", txtName.Text);
cmd.Parameters.AddWithValue("#Email", txtEmail.Text);
cmd.Parameters.AddWithValue("#City", txtboxCity.Text);
...or this...
con.Open();
SqlCommand cmd = new SqlCommand(#"insert into tbl_insert values(#name,#email,#add)", con);
cmd.Parameters.AddWithValue("#name", txtname.Text);
cmd.Parameters.AddWithValue("#email", txtemail.Text);
cmd.Parameters.AddWithValue("#add", txtadd.Text);
cmd.ExecuteNonQuery();
con.Close();
...should work fine.

"Number of query values and destination fields are not the same"

try
{
connection.Open();
OleDbCommand komanda = new OleDbCommand();
command.Connection = konekcija;
command.CommandText = "insert into EmployeeData (FirstName,LastName,Pay) values('"+txt_fname.Text+"','"+txt_lname.Text+"','"+txt_pay.Text+"')";
command.ExecuteNonQuery();
MessageBox.Show("data saved");
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show("error"+ex);
}
The root of the problem is that you don't actually know what query you're executing. Because you're executing any code that your users send you.
In most non-edge cases this appears to "work just fine" (which is why it often goes unnoticed), in some cases it causes a syntax or structural error in the query (which is what's happening here), and in some cases users take advantage of it to execute arbitrary code on your database.
This is called a SQL injection vulnerability.
You'd correct this by using query parameters which treat user input as values instead of as executable code. Something like this:
command.CommandText = "insert into EmployeeData (FirstName,LastName,Pay) values(?,?,?)";
command.Parameters.Add("#FirstName", OleDbType.VarChar, 50).Value = txt_fname.Text;
command.Parameters.Add("#LastName", OleDbType.VarChar, 50).Value = txt_lname.Text;
command.Parameters.Add("#Pay", OleDbType.VarChar, 50).Value = txt_pay.Text;
command.ExecuteNonQuery();
Note that I've guessed on the OleDbType and size of the columns. Adjust as necessary for your table structure.

Insert statement into SQL Server db

I'm developing an ASP.NET MVC Web Application using SQL Server.
I am trying to INSERT a new entry into my database and I don't understand what am I doing wrong.
I get an exception on the line:
command.ExecuteNonQuery();
The code is:
try
{
SqlConnection connection = new SqlConnection(#"Data Source=.\SQLEXPRESS;Initial Catalog=UniversityManager;Integrated Security=True");
using (connection)
{
//SqlCommand command = new SqlCommand(
// "INSERT INTO Students VALUES(#Id, #Name, #Surname, #Year, #PhoneNumber, #Cnp);",
// connection);
connection.Open();
String sql = "INSERT INTO Students(Id,Name,Surname,Year,PhoneNumber,Cnp) " +
"VALUES (#Id, #Name, #Surname, #Year, #PhoneNumber, #Cnp)";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.Add("#Id", SqlDbType.Int);
command.Parameters["#Id"].Value = 5;
command.Parameters.Add("#Name", SqlDbType.VarChar);
command.Parameters["#Name"].Value = collection.Name;
command.Parameters.Add("#Surname", SqlDbType.VarChar);
command.Parameters["#Surname"].Value = collection.Surname;
command.Parameters.Add("#Year", SqlDbType.Int);
command.Parameters["#Year"].Value = collection.Year;
command.Parameters.Add("#PhoneNumber", SqlDbType.VarChar);
command.Parameters["#PhoneNumber"].Value = collection.PhoneNumber;
command.Parameters.Add("#Cnp", SqlDbType.VarChar);
command.Parameters["#Cnp"].Value = collection.Cnp;
command.ExecuteNonQuery();
connection.Close();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Thank you!
YEAR is a reserved keyword for Sql Server. So, if you really have a column with that name, then you need to enclose it in square brackets every time you refer to it. Better change that name
String sql = "INSERT INTO Students(Id,Name,Surname,[Year],PhoneNumber,Cnp) " +
"VALUES (#Id, #Name, #Surname, #Year, #PhoneNumber, #Cnp)";
Another possibility is the Id column. If this column has the IDENTITY property set to true, then you should not set a value for it. It is automatically calculated by the database engine.
Looking at your innerexception message, it seems the problem is due to one or more of your parameters contains more text than allowed by the database field size.
You could try something like this (for each varchar parameter)
// Assuming the Name field is defined as varchar(15)
command.Parameters.Add("#Name", SqlDbType.VarChar, 15);
command.Parameters["#Name"].Value = collection.Name;
The String or binary data would be truncated exception means you're trying to insert a value that is too large for one of the columns in your Student table. For example, your Name field has a maximum length of 10 but you're trying to insert a 15 character name.
Check the values you're inserting and see if they're too large for the columns.

Categories

Resources