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?
Related
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.
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.
Hi guys I have got a simple insert statement, I know something is missing as when I click the button to insert the data it dose not insert.
any ideas?
protected void saveyear_Click(object sender, EventArgs e)
{
OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\ASPNetDB.mdb;Persist Security Info=True");
OleDbDataAdapter da = new OleDbDataAdapter();
da.InsertCommand = new OleDbCommand("INSERT INTO DVD_Infomation (Year) VALUES (#Year)", connection);
{
da.InsertCommand.Parameters.AddWithValue("#Year", Year.Text);
}
connection.Open();
da.InsertCommand.ExecuteNonQuery();
connection.Close();
}
YEAR is a reserved keyword for MS-Access Jet.
If you want to use it as name of your column you should enclose it in square brackets
da.InsertCommand = new OleDbCommand("INSERT INTO DVD_Infomation ([Year]) VALUES (#Year)", connection);
{
da.InsertCommand.Parameters.AddWithValue("#Year", Year.Text);
}
If it is still possible, I suggest to change the name of that column. It will be annoying to stump on this error every time you try to use that column in your statements
As a side note, I would write the code above as
using(OleDbConnection connection = new OleDbConnection(.....))
using(OleDbCommand cmd = new OleDbCommand("INSERT INTO DVD_Infomation ([Year]) VALUES (#Year)", connection))
{
cmd.Parameters.AddWithValue("#Year", Year.Text);
connection.Open();
cmd.ExecuteNonQuery();
}
Adding the using statement around the creation of the connection and the command will ensure a proper closing and disposing of these objects also in case of exceptions and keep your program more resource usage friendly
Never use a Reserved word in your tables, if you can help it. Since YEAR is a Reserved word, you need to use brackets around the name. Preferrably, change the field name in your table to avoid that issue in the future. Similarly, using field names with spaces in them is also frowned upon as it, too, creates problems when referencing them.
I'm creating a temporary table and populating it with two separate statements using the same command and connection. However, I'm getting an 'Invalid object name' if I create the table with the parameter inserted before the create. If I add it after the create, it works fine.
The temporary table is supposed to last the entire session, so I don't see what it matters when the parameter is added to the command object.
FAILS:
using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TEST;Integrated Security=True;"))
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.Parameters.Add(new SqlParameter("#ID", 1234));
cmd.CommandText = "CREATE TABLE #Test (ID INT NOT NULL PRIMARY KEY, I INT NOT NULL)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO #Test VALUES (#ID, 1)";
cmd.ExecuteNonQuery();
..... more code that uses the table
}
WORKS:
using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TEST;Integrated Security=True;"))
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "CREATE TABLE #Test (ID INT NOT NULL PRIMARY KEY, I INT NOT NULL)";
cmd.ExecuteNonQuery();
cmd.Parameters.Add(new SqlParameter("#ID", 1234));
cmd.CommandText = "INSERT INTO #Test VALUES (#ID, 1)";
cmd.ExecuteNonQuery();
..... more code that uses the table
}
edit:
SQL Profiler shed more light on this.
If the command has any parameters, the underlying code is issuing an "exec sp_executesql". If the Parameters are cleared, the underlying code issues a more direct "CREATE TABLE". Temp tables are cleaned up after an sp_executesql, which explains what I'm seeing here.
To me, this would be a bug in the SqlCommand (or related) code but since I now have an explanation I can move on.
The problem is in fact in "exec sp_executesql" statement. When ADO detects that there are parameters declared in the sqlCommand, uses by default "sp_executesql" instead of "exec". But in this case, the first command is creating a TEMPORAL table and, as known, temporal tables are only valid inside a stored procedure (sp_executesql) and are deleted when exit. So consequently the second INSERT statement is not longer valid in the first example code. In the second one, the temporal table is created sucessfully and the insert statement is executed normally. Hope it helps.
I suspect the state of the first execution fails because it insists that each parameter must be used.
I am doing a simple login form using winforms and access 2010 database (.accdb) in C#.
I have the following code and it seems that the connection string is wrong. I have tried searching and found that .Jet is for access 07?? but this doesnt seem to work too.
i am an amateur at databases (code referred from msdn). I am having trouble understand which should i use for this example too.
access table name: haha
ID (PK) | password
-----------------------
1 | testing
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\BC207\test.accdb");
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand();
comm.CommandText = "SELECT HAHA(*) FROM password";
comm.CommandType = CommandType.Text;
comm.Connection = conn;
conn.Open();
Object returnValue = comm.ExecuteScalar();
conn.Close();
MessageBox.Show((string)returnValue);
edited: the table's name is password, and the field that i want to get the value is ID.
SQL statement i wrote it as : SELECT ID FROM password
and yes, only one record in only one field in the table as the primary key.
anyway the problem is that the program hangs upon execution on the first line
-> Keyword not supported: 'provider'.
so i figured that I have a wrong connection string..
For Acces databases (.mdb, .accdb, etc...), you want to use OleDbConnection, not SqlConnection (SQL Server), like this:
conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\BC207\test.accdb")
Edit: as pointed out, for access OleDbConnection should be used, not SqlConnection...
you can use a much more compact way and also be sure connection is closed and disposed in any possible case even when exceptions are thrown, by using the using statements:
your query text was also, probably wrong as others have suggested...
using (var conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\BC207\test.accdb"))
using (var comm = conn.CreateCommand())
{
comm.CommandText = "SELECT password FROM HAHA";
comm.CommandType = CommandType.Text;
conn.Open();
var returnValue = comm.ExecuteScalar();
MessageBox.Show(returnValue.ToString());
}
Edit: are you sure the table HAHA only contains one row? Because the ExecuteScalar returns only one value, if you want to get 1 column but from many records you could use a DataReader or a DataSet...
comm.CommandText = "SELECT HAHA(*) FROM password";
It´s wrong.
"SELECT password FROM HAHA"
Your SQL statement should be,
SELECT * from HAHA
OR
SELECT [Password] From HAHA
EDIT:
You should change the ConnectionString.