Cannot insert duplicate key in object - c#

I have problem, although i checked primary key does not exist in the database. Additional information:
Additional information: Violation of PRIMARY KEY constraint
'PK_Yeucaukhachhang'. Cannot insert duplicate key in object
'dbo.Yeucaukhachhang'. The duplicate key value is (MH01123123).
using (SqlConnection sqlCon = new SqlConnection(sqlCnt))
{
for (int i = 0; i < metroGrid2.Rows.Count; i++)
{
SqlCommand cmd = new SqlCommand("INSERT INTO
Yeucaukhachhang(MaKH,MaHang,TenHang,DonViTinh,Dongia,
SoLuong,Duyet) values('"+ makh.Text+"','"+
metroGrid2.Rows[i].Cells["mahang"].Value +
"','"+metroGrid2.Rows[i].Cells["tenhang"].Value+"', '"+
metroGrid2.Rows[i].Cells["donvitinh"].Value+"', '"+
metroGrid2.Rows[i].Cells["dongia"].Value+"', '"+
metroGrid2.Rows[i].Cells["soluong"].Value+"', 'N')", sqlCon);
SqlCommand cmd1 = new SqlCommand("INSERT INTO DanhMucKhachHang(MaKhachHang,TenKhachHang,DiaChiKhachHang,SDTKhachHang,CMD,masothue,thanhtoan,nganhang,taikhoannganhang,ngaythang,MaHang,TenHang,DonViTinh,Dongia,SoLuong,Duyet) VALUES(#MaKhachHang,#TenKhachHang,#DiaChiKhachHang,#SDTKhachHang,#CMD,#masothue,#thanhtoan,#nganhang,#taikhoannganhang,#ngaythang)", sqlCon);
cmd1.Parameters.AddWithValue("#MaKhachHang", makh.Text);
cmd1.Parameters.AddWithValue("#TenKhachHang", namekh.Text);
cmd1.Parameters.AddWithValue("#DiaChiKhachHang", address.Text);
cmd1.Parameters.AddWithValue("#SDTKhachHang", phone.Text);
cmd1.Parameters.AddWithValue("#CMD", idkh.Text);
cmd1.Parameters.AddWithValue("#masothue", idthue.Text);
cmd1.Parameters.AddWithValue("#thanhtoan", deliver.Text);
cmd1.Parameters.AddWithValue("#nganhang", bank.Text);
cmd1.Parameters.AddWithValue("#taikhoannganhang", idacc.Text);
cmd1.Parameters.AddWithValue("#ngaythang", this.datekh.Value);
sqlCon.Open();
cmd.ExecuteNonQuery();
cmd1.ExecuteNonQuery();
sqlCon.Close();
MessageBox.Show("Thêm thành công, đa chuyển qua xác nhận yêu cầu");
LTQL.Home.Home cort = new LTQL.Home.Home();
cort.Show();
this.Hide();
}

It is impossible for us to tell whether you really have a key violation or not but I have never seen SQL make that error incorrectly.
However, I can at least give you some pointers in trying to track down the error.
First, I would recommend you rewrite your code to build your command something like this:
string szCommand = "INSERT INTO Yeucaukhachhang(MaKH,MaHang,TenHang,DonViTinh,Dongia,
SoLuong,Duyet)";
szCommand += string.Format("values ('{0}','{1}','{2}','{3}','{4}','{5}')",
makh.Text, metroGrid2.rows[i].cells["mahang"].Value,
metroGrid2.Rows[i].Cells["tenhang"].Value,
metroGrid2.Rows[i].Cells["donvitinh"].Value,
metroGrid2.Rows[i].Cells["dongia"].Value,
metroGrid2.Rows[i].Cells["soluong"].Value);
SqlCommand cmd = new SqlCommand(szCommand,sqlCon);
In case you are not familiar with string.format, the thing to remember is that the numbers inside the {} refer to the parameters after the closing"
This eliminates the necessity to double-check that you have all your 's and "s in exactly the right places and orders and makes your code much easier to read when you go back to it later.
Then, if you still have a problem, just write szCommand to a text file someplace:
using (StreamWriter sw = new StreamWriter(#"C:\temp\log.txt", true))
{
sw.WriteLine(szCommand);
sw.Close();
}
This will show you exactly what is getting passed to your command object.
Hope this helps.

Related

SqlException : Incorrect syntax near '1'

I am currently trying to implement SQL into a project with Unity3D. So far, I was able to do "normal" UPDATE, ADD, DELETE, DROP, ALTER, INSERT".
Trying to go a step further, I am trying to insert prepared statements, using this link as a guide
Here is my code :
SqlConnection sqlConnection = new SqlConnection(Connection.connectionString)
sqlConnection.Open();
SqlCommand cmd = new SqlCommand(null, sqlConnection);
cmd.CommandText = "INSERT INTO IngredientTypes (Name) VALUES (#name)";
SqlParameter nameParam = new SqlParameter("#name", SqlDbType.Text, 155);
nameParam.Value = Name;
cmd.Parameters.Add(nameParam);
cmd.Prepare();
cmd.ExecuteNonQuery();
My table looks like so :
CREATE TABLE IngredientTypes
(
IngredientTypeID INT IDENTITY(1,1) PRIMARY KEY,
Name VARCHAR(155)
);
I get this error :
SQLException : Incorrect systax near '1'.
System.Data.SqlClient.SqlConnection.ErrorHandler (System.Object sender, Mono.Data.Tds. Protocol.TdsInternalErrorMessageEventArgs e)
Help please? Thank you in advance.. I can't find where I did wrong.
You can reduce that code quite a bit with no loss of function, and even some important improvements (for example, this will close the connection even if an exception is thrown):
using (var sqlConnection = new SqlConnection(Connection.connectionString))
using (var cmd = new SqlCommand("INSERT INTO IngredientTypes (Name) VALUES (#name)", sqlConnection))
{
cmd.Parameters.Add("#name", SqlDbType.VarChar, 155).Value = Name;
sqlConnection.Open();
cmd.ExecuteNonQuery();
}
I'm not sure what's causing that exception in your existing code, though, because 1 is not used anywhere in that query. I suspect the problem has something to do with SqlDbType.Text, since that is not the correct type to use with a VarChar column, but it seems just as likely there's code somewhere we haven't seen yet that's changing your SQL command text.
Definitely the Prepare() method in your link is not needed for Sql Server. It's inherited here from DbCommand, where it's included because it's an important part of the API for some other databases, but Sql Server has handled this automatically for more than 10 years now.
SqlDbType.Text Is not the same as varchar. I don’t believe Text types have a length you specify.
Could you try below? Using the "using" structure is safer for sql connections by the way, the connection automatically closes when your process is done.
using (SqlConnection sqlConnection = new SqlConnection(Connection.connectionString))
{
SqlCommand command = new SqlCommand("INSERT INTO IngredientTypes (Name) VALUES (#name)", connection);
command.Parameters.Add("#name", SqlDbType.Varchar, 155);
command.Parameters["#name"].Value = Name; //make sure Name is string.
try
{
sqlConnection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
I tried your code exactly as it is and found no issue. Though there are few compilation errors (missing ; in line 1 and Name variable should be coming as parameter) but I am sure you know that. If you have posted your table structure and code exactly the same as you have in your project, then there is no problem in this code.

How to delete from Access database from C#

I am trying to add code that will delete from 2 tables in access db file. Sometimes one of them will work and the other wont then when I try it another way it will do the opposite. So in the end only 1 of the 2 works.
Here is my code I hope someone can spot something I did wrong.
try
{
Conn.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = Conn;
command.CommandText = "DELETE FROM TBLNAME WHERE name =#name";
command.Parameters.AddWithValue("#name", lvlist.SelectedItems[0].Text);
command.ExecuteNonQuery();
command.CommandText = "DELETE from TBLNAME WHERE cb_listName =#listname";
command.Parameters.AddWithValue("#listname", lvlist.SelectedItems[0].Text);
command.ExecuteNonQuery();
Conn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
}
You should use different Command instances, one for each command you want to execute. If you do not do that then you need to clear the parameters. This is because parameters in OleDb queries are positional and not named. This means that when you add the 2nd parameter in the 2nd query the first parameter is used because it is first in the list.
using(var connection = new OleDbConnection("connection string here"))
{
connection.Open();
using(var command = new OleDbCommand("DELETE FROM TBLNAME WHERE name = #name", connection))
{
cmd.Parameters.Add(new OleDbParameter("#name", OleDbType.VarChar, 50)).Value = lvlist.SelectedItems[0].Text;
command.ExecuteNonQuery();
}
using(var command = new OleDbCommand("DELETE from TBLNAME WHERE cb_listName = #listname", connection))
{
cmd.Parameters.Add(new OleDbParameter("#listname", OleDbType.VarChar, 50)).Value = lvlist.SelectedItems[0].Text;
command.ExecuteNonQuery();
}
}
Also you should:
Use using blocks to ensure connections are closed after use. Do not try to create class scoped, or even worse global, connection instances.
You should also specify the db type for your parameters and do not use AddwithValue.
When possible also specify the length for your db types, in the above this is possible if you have a varchar type. note I toke a guess at your schema length for these columns
Finally, just a note on general best practices, do not add catch blocks that do nothing useful with the exception. At least log the type, message, and the stack trace and then repeat this recursively for each inner exception found in property InnerException. This useful information can help you figure out exactly why an exception occurred.
Use two different OleDbCommand objects.

ERROR : The multi-part identifier could not be bound, c# console Application

SqlConnection cn = new SqlConnection("user id=ID;" +
"password=PASS;server=svr;" +
"Trusted_Connection=no;" +
"database=db; " +
"connection timeout=30");
cn.Open();
SqlCommand command1 = new SqlCommand();
command1.Connection = cn;
Console.WriteLine(ListofOrders.Count);
for (int i = 0; i < ListofOrders.Count; i++)
command1.CommandText += string.Format("update table set Status='Expired' where GUID={0};", ListofOrders[i].ToString());
command1.ExecuteNonQuery();
// LogicHandler.UpdateActiveOrders();
Console.WriteLine("DONE", ConsoleColor.Cyan);
Getting error at this step: command1.ExecuteNonQuery(); Error Message: The multi-part identifier could not be bound.
What i am trying here is I am running a select query and getting that data into the ListofOrders list from that I wanna run the update to those data in the list.
Please help
If you use a Reserved Keyword like table you have to wrap it in square brackets: [table]. But it would be better to not use them in the first place.
I guess you need to wrap the Guid with apostrophes like in GUID='{0}'. Howver, you should use sql-parameters instead of string concatenation, always. That prevents also sql-injection.
string update = #"update tablename -- or [Table] but i wouldnt do that
set Status='Expired'
where GUID=#GUID";
command1.CommandText = update;
command1.Parameters.Add("#GUID", SqlDbType.UniqueIdentifier).Value = new Guid(ListofOrders[i].ToString());
As an aside, why have you used command1.CommandText += instead of just command1.CommandText =? That is at least confusing, if you reuse the command it could also cause errors.

C# error Must declare the scalar variable

I am getting the following error and I have been doing a lot of research online to re-solve but i can't seem to find the right answer , A bit of help would be much appreciated.
Many Thanks
Error: Additional information: Must declare the scalar variable
"#Username#DepartmentName".
//DepartmentName and Username are both foreign key from LoginDetails table and Department table
SqlConnection cn = new SqlConnection(#"Data Source=PRINCENICHOLAS;Initial Catalog=Kids Company IT Asset;Integrated Security=True");
SqlCommand sqlcmdLogin = new SqlCommand("Insert into LoginDetails(Username,Password,PrivilegeCode) Values(#Username,#Password,#PrivilegeCode)", cn);
sqlcmdLogin.Parameters.AddWithValue("#Username", txtEmpFirstName.Text + '.' + txtEmpSurname.Text);
sqlcmdLogin.Parameters.AddWithValue("#Password", txtEmpPassword.Text);
sqlcmdLogin.Parameters.AddWithValue("#PrivilegeCode", cboPrivilege.SelectedItem.ToString());
cn.Open();
sqlcmdLogin.ExecuteNonQuery();
cn.Close();
//Insert Employee Table
SqlCommand sqlcmdEmp = new SqlCommand("Insert into Employee(FirstName,LastName,DOB,Email,PhoneNumber,JobRole,Username,DepartmentName) Values(#FirstName,#LastName,#DOB,#Email,#PhoneNumber,#JobRole,#Username#DepartmentName)", cn);
sqlcmdEmp.Parameters.AddWithValue("#FirstName", txtEmpFirstName.Text);
sqlcmdEmp.Parameters.AddWithValue("#LastName", txtEmpSurname.Text);
sqlcmdEmp.Parameters.AddWithValue("#DOB", dtpEmpDOB.Text);
sqlcmdEmp.Parameters.AddWithValue("#Email", txtEmpEmail.Text);
sqlcmdEmp.Parameters.AddWithValue("#PhoneNumber", txtEmpPhone.Text);
sqlcmdEmp.Parameters.AddWithValue("#JobRole", txtJobRole.Text);
sqlcmdEmp.Parameters.AddWithValue("#Username", txtEmpFirstName.Text + '.' + txtEmpSurname.Text);
sqlcmdEmp.Parameters.AddWithValue("#DepartmentName", cboDeptName.SelectedItem.ToString());
cn.Open();
sqlcmdEmp.ExecuteNonQuery();
cn.Close();​
You forget to seperate your parameter names with , like
#Username, #DepartmentName
in your sqlcmdEmp definition line.
Since you wrote it as #Username#DepartmentName, your program expect the exact name of it.
Use using statement to dispose your SqlConnection and SqlCommand instead of calling .Close() method manually.
using(SqlConnection cn = new SqlConnection(connectionString))
using(SqlCommand cmd = cn.CreateCommand())
{
// Define your command text
// Add your paramter values
// Open your connection
// Execute your query
}
Don't store your passwords as a plain text. Read: Best way to store password in database
And don't use AddWithValue method. It may generate unexpected results sometimes. Use .Add() method or it's overloads. Read: Can we stop using AddWithValue() already?

Deleting records from a table, is this correct?

I want to delete some record from table ,by running this Query in C# is it Correct or not,
Please help me
SqlCommand cmdRe = new SqlCommand("insert into msisdn_master SELECT * from tblDeactive
where msisdn in (" + str_MSISDN + ")", cn);
SqlCommand cmdRed = new SqlCommand("delete from tblDeactive where msisdn in ("+str_MSISDN+")", cn);
cmdRe.CommandType = CommandType.Text;
cmdRed.CommandType = CommandType.Text;
note : str_MSISDN is the StringBuilder which stores the Number which is inserted in TextField.
You should be using proper SQL parameters. NEVER use string building since that leaves you open for injection attacks.
Read this tutorial to learn how to add parameters to SqlCommands.

Categories