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.
Related
I have 2 tables which are tableCustomerLogin and tableCustomerRegister. There is Foreign Key for the tableCustomerLogin i.e. cust_id.
In the tableCustomerLogin, I have tableCustomerLogin
cust_login_id
cust_id
cust_email
cust_username
cust_password
and for tableCustomerRegister,
tableCustomerRegister
cust_id
cust_fullname
cust_username
cust_email
cust_password
cust_mobile_number
cust_image
cust_address1
cust_address2
cust_city
cust_postcode
cust_create_acc_time
When customer register, the data will store in the tableCustomerRegister. How to make it register in the tableCustomerLogin?
string sql = #"INSERT INTO tableCustomerRegister VALUES (#cust_fullname, #cust_username, #cust_email, #password, #cust_mobile_phone, #cust_address1, #cust_address2, #cust_image, #cust_city, #cust_state, #cust_postcode, #cust_create_acc_time, #role, #enabled)";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#cust_fullname", txtFirstName.Text + " " + txtLastName.Text);
cmd.Parameters.AddWithValue("#cust_username", txtUsername.Text);
cmd.Parameters.AddWithValue("#cust_email", txtEmail.Text);
cmd.Parameters.AddWithValue("#password", passwordhash);
cmd.Parameters.AddWithValue("#cust_mobile_phone", txtMobilePhone.Text);
cmd.Parameters.AddWithValue("#cust_address1", txtAddress1.Text);
cmd.Parameters.AddWithValue("#cust_address2", txtAddress2.Text);
cmd.Parameters.AddWithValue("#cust_image", txtProfilePicture.Text);
cmd.Parameters.AddWithValue("#cust_city", ICityString());
cmd.Parameters.AddWithValue("#cust_state", ddState.SelectedValue.ToString());
cmd.Parameters.AddWithValue("#cust_postcode", txtPostcode.Text);
cmd.Parameters.AddWithValue("#cust_create_acc_time", DateTime.Now);
cmd.Parameters.AddWithValue("#role", "user");
cmd.Parameters.AddWithValue("#enabled", enabled);
try
{
conn.Open();
cmd.ExecuteNonQuery();
lblStatus.Text = "Status: Data successfully saved.";
}
well, first of all you need to change your query
string sql = #"INSERT INTO tableCustomerRegister OUTPUT INSERTED.cust_id VALUES (#cust_fullname, #cust_username, #cust_email, #password, #cust_mobile_phone, #cust_address1, #cust_address2, #cust_image, #cust_city, #cust_state, #cust_postcode, #cust_create_acc_time, #role, #enabled)";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#cust_fullname", txtFirstName.Text + " " + txtLastName.Text);
cmd.Parameters.AddWithValue("#cust_username", txtUsername.Text);
//so on (all your parameters)
var custid = (int)cmd.ExecuteScalar()
ExecuteScalar return int, in this case it will return cust_id as your query have OUTPUT INSERTED.cust_id. Now You have your inserted cust_id saved in tableCustomerRegister. Now all you need to do just write another query for save data into your tableCustomerLogin with foreign key cust_id. like this,
string Sql2 = "INSERT INTO tableCustomerLogin (column_names) VALUES (parameters values)";
SqlCommand cmd = new SqlCommand(sq2, conn);
cmd.Parameters.AddWithValue("#cust_id",custid); //as foreign key
//all other Parameters
You can first insert a tableCustomerRegister record and then insert another data the tableCustomerLogin table. You would be better do this in the transaction block.
The other way , You can add a trigger to the tableCustomerLogin table.
CREATE TRIGGER trg_tableCustReg ON tableCustomerRegister
FOR INSERT
AS
/*
* if CustLoginID is a identity , no dont need to add
*/
INSERT INTO tableCustomerLogin
(cust_login_id, cust_id, cust_email, cust_username, cust_password)
Select
'CustLoginID',
cust_id ,
cust_email,
cust_username,
user_password
FROM inserted
go
Probably the best solution is to follow the DRY principle, Dont Repeat Yourself.
I think that you can store all information in a single table customer_table for example and then retrive the necessary data with a more simple logic from only this table.
Instead, if you want to stay on your actual data structure, simply add new insert statement after firstseparate by semicolon
how to insert data into multiple tables at once
there are two different way. you shold use SCOPE_IDENTITY
string sql = #"INSERT INTO tableCustomerRegister VALUES (#cust_fullname, #cust_username, #cust_email, #password, #cust_mobile_phone, #cust_address1, #cust_address2, #cust_image, #cust_city, #cust_state, #cust_postcode, #cust_create_acc_time, #role, #enabled) SELECT SCOPE_IDENTITY()";
SCOPE_IDENTITY Returns the last identity value inserted into an
identity column in the same scope
var newId= cmd.ExecuteScaler();
newId created new Primary Key ID for you cust_id
you have this ID(cust_id) and you can register in the Login table.
INSERT INTO tableCustomerLogin (cust_login_id,**cust_id**,cust_email,cust_username,cust_password)
cust_id = newId
If Cust_id is auto-created in the tableCustomerRegister table, then you can save the same id in the tableCustomerLogin table (cust_id). then only your foreign Key relation work.
try
{
conn.Open();
cmd.ExecuteNonQuery();
SqlCommand get_custid_cmd = new SqlCommand("select ##identity", conn);
int cust_id = Convert.ToInt32(get_custid_cmd.ExecuteScalar());
string sql_insert = #"INSERT INTO tableCustomerLogin VALUES (#cust_id, #cust_username, #cust_email, #password)";
SqlCommand cmd_insert = new SqlCommand(sql_insert, conn);
cmd_insert.Parameters.AddWithValue("#cust_id",cust_id);
cmd_insert.Parameters.AddWithValue("#cust_username", txtUsername.Text);
cmd_insert.Parameters.AddWithValue("#cust_email", txtEmail.Text);
cmd_insert.Parameters.AddWithValue("#password", passwordhash);
cmd_insert.ExecuteNonQuery();
lblStatus.Text = "Status: Data successfully saved.";
}
When i tried to insert, the error 'not enough values' appears.
public int CreateAdmin( string product_name, string quality, string quantity, string price, string product_image)
{
string connectionString = "User Id=hr;Password=hr;Data Source=localhost:1521/xe";
OracleConnection orc = new OracleConnection();
orc.ConnectionString = connectionString; //assign connection
//OracleDataAdapter da = new OracleDataAdapter();
orc.Open();
OracleCommand cmd = new OracleCommand();//object of command
cmd.Connection = orc;
cmd.CommandType = CommandType.Text; // declare command type
cmd.CommandText = "insert into Product values( :b, :c, :d, :a, :p)";
cmd.Parameters.Add("#b", product_name); //add paramenter
cmd.Parameters.Add("#c", quality);
cmd.Parameters.Add("#d", quantity);
cmd.Parameters.Add("#a", price);
cmd.Parameters.Add("#p", product_image);
//da.InsertCommand = cmd;
int i = cmd.ExecuteNonQuery();
orc.Close();
return i;
}
Your paramnames are wrong, they need to be named as the one you set in params - you use :a in the command and #a when setting the parameter. Parameter start with # (for SqlServer) or : (for OracleServer).
If your table has more columns than those 5 you have to provide them as well, else the db does not know where to put the given parameters. (an auto-inc ID additionally is fine, if thats your 6th column it will work).
public int CreateAdmin (string product_name, string quality, string quantity, string price, string product_image)
{
string connectionString = "User Id=hr;Password=hr;Data Source=localhost:1521/xe";
using (var orc = new OracleConnection (connectionString))
{
using (var cmd = orc.CreateCommand ())
{
cmd.CommandType = CommandType.Text; // declare command type
// Product has exactly 5 or 5 + 1 auto-inc ID column, else provide the
// column names as well:
// insert into Product ( name,qual,quant,price,img ) values( :b, :c, :d, :a, :p)";
cmd.CommandText = "insert into Product values( :b, :c, :d, :a, :p)";
cmd.Parameters.Add (":b", product_name); //add paramenter
cmd.Parameters.Add (":c", quality);
cmd.Parameters.Add (":d", quantity);
cmd.Parameters.Add (":a", price);
cmd.Parameters.Add (":p", product_image);
//da.InsertCommand = cmd;
int i = cmd.ExecuteNonQuery ();
return i;
}
}
}
I changed your code to benefit from using(var orc = new OracleConnection()) { .... }-pattern with IDisposables - it auto-close/disposes your connection (same for command) on leaving the scope.
Edited due to comment by Wernfried-Domscheit:
Oracle needs : (# is for SqlServer) - this answer how-to-write-parameterized-oracle-insert-query supports it - it even uses parameter names without : - so perhaps parameternames are just inserted by "order" instead of "by name"
You have two options for saving an image to your DB:
Convert your image to Base64 and save the output string to your DB
Save your image as a file on your server and save the path of this image to your DB (Recommended)
You will most likely have more columns in your Product table than you give in your values list. Explicitly give column names:
OracleCommand cmd = new OracleCommand();//object of command
cmd.Connection = orc;
cmd.CommandType = CommandType.Text; // declare command type
// explicitly add column names
cmd.CommandText = "insert into Product (product_name, quality, quantity, price, product_image) values( :b, :c, :d, :a, :p)";
cmd.Parameters.Add(":b", product_name); //add paramenter
cmd.Parameters.Add(":c", quality);
cmd.Parameters.Add(":d", quantity);
cmd.Parameters.Add(":a", price);
cmd.Parameters.Add(":p", product_image);
int i = cmd.ExecuteNonQuery();
Please change the column names in the above code to match your column names in your table. Let us know if that worked for you.
Edit
As stated by Patrick Artner in his well-written answer, the parameter name placeholders had to be the same in the CommandText and when adding the parameters to the command. When using OracleCommand, the placeholder needs to be : rather than # as stated in the MSDN OracleCommand.Parameters page.
I am trying to update my ms access db with windows application and I am having a hard time. When I run it I don't get any errors but it does update like once or twice when I test it but then doesn't work again if I do it again a third time.
This is the code I use
Conn.Open();
Command.CommandType = CommandType.Text;
Command.CommandText ="UPDATE TABLE SET c_qty=#qty WHERE id = #ID";
Command.Parameters.AddWithValue("#qty", txtQty.Text);
Command.Parameters.AddWithValue("#ID", txtID.Text);
Command.ExecuteNonQuery();
Conn.Close();
I felt I was doing this right or on the right track of having it correct but seems to be more of a issue then I thought. Any help would be great
Quantity and Id are hopefully integers and you should pass them as such.
Also Table is a reserved word, if this really is the name of your table you should enclose it with square brackets.
You should also pass in the correct db types in your parameters and not use AddWithvalue which does not allow this.
Code
Conn.Open();
Command.CommandType = CommandType.Text;
Command.CommandText ="UPDATE [TABLE] SET c_qty= ? WHERE id = ?";
Command.Parameters.Add(new OleDbParameter("#qty", OleDbType.Int) {Value = int.Parse(txtQty.Text)});
Command.Parameters.Add(new OleDbParameter("#ID", OleDbType.Int) {Value = int.Parse(txtID.Text)});
var rowsUpdated = Command.ExecuteNonQuery();
// output rowsUpdated to the log, should be 1 if id is the PK
Conn.Close();
Finally use using blocks for your Disposables. If you were to get an Exception here then connection would remain open until Garbage collection runs which means you might have a problem with other connection attempts to this Access database.
Revised with using blocks
using (OleDbConnection Conn = new OleDbConnection("connectionStringHere"))
using (OleDbCommand Command = new OleDbCommand("UPDATE [TABLE] SET c_qty= ? WHERE id = ?", Conn))
{
Command.Parameters.Add(new OleDbParameter("#qty", OleDbType.Int) {Value = int.Parse(txtQty.Text)});
Command.Parameters.Add(new OleDbParameter("#ID", OleDbType.Int) {Value = int.Parse(txtID.Text)});
Conn.Open();
var rowsUpdated = Command.ExecuteNonQuery();
// output rowsUpdated to the log, should be 1 if id is the PK
}
Finally OleDbCommand does not support named parameters, see OleDbCommand.Parameters
I have been trying to add the Customer_ID from the Customer table to Customer_ID in Customer_Ship table. I keep running into the Customer_ID not converting to Int properly. It's possible that I am not actually getting the new row added to Customer_Ship table first. Your help is greatly appreciated and many thanks in advance.
if (customer_ID == "")
{
string SQL = "INSERT INTO Customer (Customer_Name) VALUES (#customer_Name); SELECT Customer_ID FROM Customer WHERE Customer_ID = SCOPE_IDENTITY();";
SqlCommand sqlCommand = new SqlCommand(SQL, sqlConnection);
sqlCommand.Parameters.Add("#customer_Name", SqlDbType.VarChar, 100).Value = customer_Name;
sqlConnection.Open();
int customer_Id = (int)sqlCommand.ExecuteScalar();
SQL = "INSERT INTO Customer_Ship (Customer_ID) VALUES (#customer_Id)";
sqlCommand = new SqlCommand(SQL, sqlConnection);
sqlCommand.Parameters.AddwithValue("#customer_Id", customer_Id);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
}
Two mistakes I see:
you should be just returning SCOPE_IDENTITY - you can simplify your first INSERT statement to read:
INSERT INTO Customer (Customer_Name) VALUES (#customer_Name); SELECT SCOPE_IDENTITY();";
This will return the newly inserted Customer_ID identity value from the Customer table - no need to do this complicated SELECT that you had in your question
You need to call .ExecuteScalar() right from the beginning - don't call .ExecuteNonQuery() first and then ExecuteScalar() - that'll execute the statement twice - just use:
using(SqlCommand sqlCommand = new SqlCommand(SQL, sqlConnection))
{
sqlCommand.Parameters.Add("#customer_Name", SqlDbType.VarChar, 100).Value = customer_Name;
sqlConnection.Open();
int customer_Id = (int)sqlCommand.ExecuteScalar();
sqlConnection.Close();
}
That'll insert the values into Customer and return the newly created Customer_ID as the return value into customer_id (which already is an Int) from .ExecuteScalar(). You can then use this int value to insert into the Customer_Ship table - no conversion necessary - this already is an int
The possible reason for not converting the value is you are trying to convert an empty string(customer_ID : Refer Line :#1 of your code) and not "customer_Id " what you are fetching from the database .
I am trying to insert two values to mysql database through two textboxes using WPF and C#. I am connecting to the database successfuly but when I try to insert the data I get error: Column "user_name" can not be null. What is really confusing be is that I am entering data in the first and the second textboxes. It seems that the data to inserted in the textboxes is not passed. My question is do you know where is the problem and how to fix it?
PS: my database is very simple contain id as int16 auto incremented, name as varchar100 and user_password as varchar100
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection("host=tara.rdb.superhosting.bg;user=sozopouk;password=27051996;database=sozopouk_test2;");
MySqlDataAdapter da = new MySqlDataAdapter();
da.InsertCommand = new MySqlCommand("Insert into niki2 values (#id,#name, #user_password)", con);
da.InsertCommand.Parameters.Add("#name", MySqlDbType.VarChar).Value = textBox1.Text;
da.InsertCommand.Parameters.Add("#user_password", MySqlDbType.VarChar).Value=textBox2.Text;
con.Open();
da.InsertCommand.ExecuteNonQuery();
con.Close();
}
Guys after I did couple of changes I am getting this error message:
Unknown column 'name' in 'field list'
Here is edited code:
private void button1_Click(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection("host=tara.rdb.superhosting.bg;user=sozopouk;password=27051996;database=sozopouk_test2;");
MySqlDataAdapter da = new MySqlDataAdapter();
da.InsertCommand = new MySqlCommand("INSERT INTO niki (name, user_password) VALUES (#name, #user_password)", con);
da.InsertCommand.Parameters.Add("#name", MySqlDbType.VarChar).Value = textBox1.Text;
da.InsertCommand.Parameters.Add("#user_password", MySqlDbType.VarChar).Value=textBox2.Text;
con.Open();
da.InsertCommand.ExecuteNonQuery();
con.Close();
}
When I replace name with user_name and try to insert data I get an error ** Column "user_name" cannot be null**
The affected line is :
da.InsertCommand.ExecuteNonQuery();
Do you have any idea how to solve it?
Look at your code:
da.InsertCommand.Parameters.Add("#user_id", MySqlDbType.Int16).Value = "";
da.InsertCommand.Parameters.Add("#user_name", MySqlDbType.VarChar).Value = "";
da.InsertCommand.Parameters.Add("#user_password", MySqlDbType.VarChar).Value =
textBox2.Text;
Now look at what you've said:
It seems that the data to inserted in the textboxes is not passed.
Look at the code again. Look at the value being used for user_name (and indeed user_id). How is that using a textbox value? How are you expecting the data from textBox1 to get to the database when your code never mentions it?
Additionally, as sblom mentions in comments, I'd encourage you to use explicit column names - at which point you won't need to specify anything for user_id, which I assume is an auto-generated identity column anyway. (It therefore doesn't make sense to try to insert an empty value into it.) It's not clear why you're trying to use an empty string as a value for an Int16 column, either...
EDIT: For your edited code:
da.InsertCommand = new MySqlCommand(
"INSERT INTO niki (name, user_password) VALUES (#name, #user_password)", con);
Given your first error, the column is user_name, not name...
Can you just check what table you want to use exactly?
in your actual question it was
da.InsertCommand = new MySqlCommand("Insert into **niki2** values (#id,#name, #user_password)", con);
and in updated question the table name is changed to
da.InsertCommand = new MySqlCommand("INSERT INTO **niki** (name, user_password) VALUES (#name, #user_password)", con);
I feel you have two tables you are playing with and are confused
seems like
name is in niki2 and
user_name is in niki probably your actual table.
I am sure no one can answer with this much ambiguity
Try
For Table niki
da.InsertCommand = new MySqlCommand("INSERT INTO niki (user_name, user_password) VALUES (#user_name, #user_password)", con);
For Table niki2
da.InsertCommand = new MySqlCommand("INSERT INTO niki2 (name, user_password) VALUES (#name, #user_password)", con);
OR Reversal
Luck
You haven't specified in the insert statement in which fields the values should be stored, so the values will end up in the first three fields in the order that you specified, regardless of their names. I guess that the user name field is the fourth, so it doesn't get a value, thus being null.
Specify which fields should be used:
da.InsertCommand = new MySqlCommand("INSERT INTO niki (user_id, user_name, user_password) VALUES (#user_id,#user_name, #user_password)", con);
finally I find the problem causing me this exception. As you can see my old code:
da.InsertCommand = new MySqlCommand("INSERT INTO niki (name, user_password) VALUES (#name, #user_password)", con);
da.InsertCommand.Parameters.Add("#name", MySqlDbType.VarChar).Value = textBox1.Text;
da.InsertCommand.Parameters.Add("#user_password", MySqlDbType.VarChar).Value=textBox2.Text;
enter code here
What I did was to replace the
# with ?
And basically my code looked like :
da.InsertCommand = new MySqlCommand("INSERT INTO niki (name, user_password) VALUES (?name, ?user_password)", con);
da.InsertCommand.Parameters.Add("?name", MySqlDbType.VarChar).Value = textBox1.Text;
da.InsertCommand.Parameters.Add("?user_password", MySqlDbType.VarChar).Value=textBox2.Text;
enter code here
Thanks to all who involved in the discussion!