I am new to C#. I am trying to save the numbers into a SQL Server database table (locally) but I get an error:
Cannot insert the value NULL into column
My code:
private void SaveBtn_Click(object sender, EventArgs e)
{
try
{
SqlConnection conn = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\fn1965\Desktop\Work\TESTDB\NumDB.mdf;Integrated Security=True;Connect Timeout=30");
conn.Open();
string insert_query = "INSERT into [NumericTable] (Num1, Num2, Total) VALUES (#Num1, #Num2, #Total)";
SqlCommand cmd = new SqlCommand(insert_query, conn);
cmd.Parameters.AddWithValue("#Num1", textBox1.Text);
cmd.Parameters.AddWithValue("#Num2", textBox2.Text);
cmd.Parameters.AddWithValue("#Total", textBox3.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Record saved");
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show("EROR:"+ ex.ToString());
}
}
Table schema
You can see in the image that the column Id is the only one that does not support null values. Since the column is not identity and as you are not providing a value on your insert, then the INSERT fail with the given exception. This code will work (only if there isn't a record with Id = 1 already):
string insert_query = "INSERT into [NumericTable] (Num1,Num2,Total, Id) Values (#Num1,#Num2,#Total, #id)";
SqlCommand cmd = new SqlCommand(insert_query, conn);
cmd.Parameters.AddWithValue("#Num1", textBox1.Text);
cmd.Parameters.AddWithValue("#Num2", textBox2.Text);
cmd.Parameters.AddWithValue("#Total", textBox3.Text);
cmd.Parameters.AddWithValue("#Id", 1);
cmd.ExecuteNonQuery();
I assume that this is obviously not the desired fuctionality. What you should do is either set the Id column to identity = true or set a value on the insert.
I also encourage you to not use AddWithValue method since it can lead you to some undesired problems. You can read more here: https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
That screenshot you took of your table columns design; get back to that, then click the id column, look in the Properties grid for Identity Specification (might need to expand it) and set it to Yes. Set other properties relevant to your needs and save the table.
Borrowed from another SO question:
There are ways to do this from script but they're generally longer/more awkward than using the UI in management studio.
This will (should) change th column so it auto inserts an incrementing number into itself when you insert values for other rows. Someone else has posted an answer as to how to insert values for it yourself but my recommendation to you as a learner is to use auto increment to save the additional needless complication of providing your own primary key values
Related
This is the button for inserting those fileds into my database, the field names and db connection works for any other tasks but somehow this button keeps telling me the insert failed"
private void button1_Click(object sender, EventArgs e)
{
try {
int answer;
sql = "INSERT INTO Registration VALUES (#Student_ID,#Course_ID,#Section,#Start_Date,#End_Date,#Semester)";
connection.Open();
command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("#Student_ID", comboBox1.SelectedItem.ToString());
command.Parameters.AddWithValue("#Course_ID", lstcourse.SelectedItem.ToString());
command.Parameters.AddWithValue("#Section", txtsection.Text);
command.Parameters.AddWithValue("#Start_Date", txtstart.Text);
command.Parameters.AddWithValue("#End_Date", txtend.Text);
command.Parameters.AddWithValue("#Semester", txtsemester.Text);
answer = command.ExecuteNonQuery();
command.Dispose();
connection.Close();
MessageBox.Show("You're awesome and added " + answer + " row to your registration");
}
catch
{
MessageBox.Show("You screwed up");
}
/////////////////////////////////
}
This is the table:
Registration_ID float Checked
Student_ID float Checked
Course_ID float Checked
Section float Checked
Start_Date datetime Checked
End_Date datetime Checked
Semester nvarchar(255) Checked
Unchecked
Somehow this button keeps telling me the insert failed
It would of been helpful if you could have posted the actual error from the catch statement. If you debugged the routine and specifically inspected the error message, you'd notice what was wrong.
The primary issue of the error is because you didn't supply the columns to insert into. If you supplied all columns upfront the insert statement would be satisfied and work just fine.
Solution
Either make sure all columns are accounted for in the insert statement.
Specify the columns you are inserting into.
Your table according to your post has 7 columns, you are only supplying 6 of them. When you using the syntax of INSERT INTO TABLENAME VALUES() you have to supply values for all columns, not just a select few.
On the other hand if you used the syntax of INSERT INTO TABLENAME(columnName, columnName)VALUES(value, value) you are fulfilling the requirements by supplying two columns along with their values.
Side Note:
Look into using statements to ensure objects are disposed of.
Use SqlParameterCollection.Add method instead of AddWithValue, it has to infer the data types and this could cause unintended results.
When declaring your parameters, please specify/add the correct data type and length that matches the column data type and length on the table.
Either modify your SQL statement to include the missing column:
INSERT INTO Registration VALUES (#Registration_ID,#Student_ID,#Course_ID,#Section,#Start_Date,#End_Date,#Semester)
or specify the columns that will be populated in your new row (assuming your Registration_ID field is an auto-identifier)
INSERT INTO Registration (Student_ID, Course_ID, Section, Start_Date, End_Date, Semester) VALUES (#Student_ID,#Course_ID,#Section,#Start_Date,#End_Date,#Semester)
you can try this code
using(SqlConnection connection = new
SqlConnection(ConfigurationManager.ConnectionStrings["conString"].ConnectionString))
{
connection.Open();
string sql = "INSERT INTO Table(id,name,test)
VALUES(#param1,#param2,#param3)";
using(SqlCommand cmd = new SqlCommand(sql,connection))
{
cmd.Parameters.Add("#param1", SqlDbType.Int).value = val;
cmd.Parameters.Add("#param2", SqlDbType.Varchar, 50).value = Name;
cmd.Parameters.Add("#param3", SqlDbType.Varchar, 50).value = Test;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
I got a gridview which is connected to a datasource getting values from there.I created a selectedindexchanged function to work when select is clicked.it shows ID , orderID,From,To and Price values and opens panel which has 4 textbox's and a dropdownlist if user wants to change those values.Everything is fine until here.When user changes some values and clicks submit nothing changes in database.I got the values using id ; " string id = orderGrid.SelectedRow.Cells[1].Text; "
here is my submit button code ;
protected void submitButton_Click(object sender, EventArgs e)
{
string id = orderGrid.SelectedRow.Cells[1].Text;
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("db.mdb") + ";Persist Security Info=False");
string query = "update ordersTable set orderID=#testID,fromLocation=#from,toLocation=#to,price=#price WHERE ID = #id ";
OleDbCommand cmd = new OleDbCommand(query, con);
cmd.Parameters.AddWithValue("#id", id);
cmd.Parameters.AddWithValue("#testID", orderBox.Text);
cmd.Parameters.AddWithValue("#from", fromText.Text);
cmd.Parameters.AddWithValue("#to", toList.SelectedItem.Text);
cmd.Parameters.AddWithValue("#price", priceBox.Text);
try
{
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Response.Write("Edit Complete !");
}
catch (Exception ex)
{
Response.Write("Error : " + ex);
}
orderGrid.DataBind();
}
id string works perfectly fine in my selectedindexchanged function.
In OleDb parameters are recognized by their position not by their name.
Your parameter placeholder #ID is the last one in the query, but you add it as the first one in the collection.
This result in your WHERE condition to be totally wrong
(you search for a record whose ID is equal to the content of the priceBox)
Just move the insert of the ID as last parameter
cmd.Parameters.AddWithValue("#testID", orderBox.Text);
cmd.Parameters.AddWithValue("#from", fromText.Text);
cmd.Parameters.AddWithValue("#to", toList.SelectedItem.Text);
cmd.Parameters.AddWithValue("#price", priceBox.Text);
cmd.Parameters.AddWithValue("#id", id);
This is the primary problem, but I can see another one caused by your use of AddWithValue. This is an handy shortcut, but sometime it make you pay for it.
In your case, you pass to the #price parameter a string and, if your price field is a decimal (as it should be) then the database engine will attempt a conversion from a string to a decimal and if the decimal separator is not the same you end with a wrong value in the database. Better check the value in the priceBox and convert it yourself to a decimal.
See Can we stop to use AddWithValue already?
Hello I got a big problem I am trying to add a new column to my MSSQL Database Table and i tried it like thousand times but it wont work.
My destination is to press a button then use the function "eventsspalte_Hinzufügen" to add a new column with the name thats Inserted by the user.
This is the snippet.
private void eventsspalte_Hinzufügen()
{
SQL_eingabe = "ALTER TABLE Teilnahmen_Events ADD #tbName bit NOT NULL ;"; // CONSTRAINT strconst3 DEFAULT 0
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = SQL_eingabe;
cmd.Parameters.AddWithValue("#tbName", tb_Eventname.Text);
cmd.ExecuteNonQuery();
con.Close();
}
The Exception says that cmd.ExecuteQuery() is not able to Execute the sql Command because of the wromg Syntax at #tbName I also tried to use a variable like:
ALTER TABLE Teilnahmen_Events ADD'"+ tb_Eventname.Text +"'bit NOT NULL ;";
but it also didnt work...
I hope you got an solution for me thank you very much.
you cannot pass column name as parameter.
In your second example, single quotes are not needed, so change it into
ALTER TABLE Teilnahmen_Events ADD "+ tb_Eventname.Text +" bit NOT NULL ;";
I am having an issue with the increment for the ID. The ID would increase by one every time I click insert, but the problem occurs when the ID 2, it would insert the values twice, if ID 3, it would insert the values three times, and so on.
There are couple of options that I have been trying. One is Max and the other one is finding the last inserted value and add one to the ID just.
I would appreciate if anyone can help me out with this. Thanks
public partial class LoginInfo : System.Web.UI.Page
{
static string myConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
private void GenerateID()
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myQuery1 = "Select Count(S_ID) from Student_Name";
SqlCommand cmd = new SqlCommand(myQuery1, myConnection);
myConnection.Open();
int addOneS_ID_Table1 = Convert.ToInt32(cmd.ExecuteScalar());
myConnection.Close();
addOneS_ID_Table1++;
lblstdID.Text = addOneS_ID_Table1.ToString();
myConnection.Open();
cmd.CommandText = "Select Count(P_ID) from Student_Pass";
int addOneP_ID_Table2 = Convert.ToInt32(cmd.ExecuteScalar());
myConnection.Close();
addOneP_ID_Table2++;
lblstdPass.Text = addOneP_ID_Table2.ToString();
/*-----------------------------------------------------------------*/
//SqlConnection myConnection = new SqlConnection(myConnectionString);
//SqlCommand cmd = new SqlCommand("SELECT MAX(S_ID) as max_S_ID from Student_Name",myConnection);
//cmd.CommandType = CommandType.Text;
//myConnection.Open();
//lblstdID.Text = Convert.ToString(cmd.ExecuteScalar());
//cmd.CommandText = "SELECT MAX(P_ID) as max_P_ID FROM Student_Pass";
//lblstdPass.Text = Convert.ToString(cmd.ExecuteScalar());
//myConnection.Close();
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
GenerateID();
}
}
protected void btnInsert_Click(object sender, EventArgs e)
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myQuery = "Insert into Student_Name(S_ID,STUDENT_NAME) VALUES" + "(#S_ID,#STUDENT_NAME)";
SqlCommand cmd = new SqlCommand(myQuery,myConnection);
cmd.Parameters.Add("#S_ID", SqlDbType.Int).Value = lblstdID.Text;
cmd.Parameters.Add("#STUDENT_NAME", SqlDbType.VarChar).Value = txtstdName.Text;
if(myConnection.State == ConnectionState.Closed)
{
myConnection.Open();
}
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
//Second Table
cmd.CommandText = "Insert into Student_Pass(P_ID,PASSWORD) VALUES" + "(#P_ID,#PASSWORD)";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#P_ID", SqlDbType.Int).Value = lblstdPass.Text;
cmd.Parameters.Add("#PASSWORD", SqlDbType.VarChar).Value = txtStdPass.Text;
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
myConnection.Close();
GenerateID();
lblResult.Text = "Successfully Saved";
GridView1.DataBind();
}
}
Problem is with your query since you are getting COUNT(S_ID) which is going to get you count of records doesn't necessarily will give exact ID number. You should rather try MAX(S_ID) or ORDER BY clause saying
Select MAX(S_ID) from Student_Name
(OR)
Select TOP 1 S_ID from Student_Name ORDER BY S_ID DESC;
But recommended, You should actually go with SQL Server ##IDENTITY or SCOPE_IDENTITY() to get the last inserted record ID (assuming that S_ID is an IDENTITY column)
It's highly recommended to not use max or top in order to determine the "next" identifier to use, simply because of the cost associated with it.
However, there are some other pitfalls to using max and top especially if there is a chance that nolock is used (which is a whole other conversation). I've seen a lot of web applications use max and has proven to be a performance killer.
Rahul is right, ##identity or scope_identity are good alternatives. However, I think this calls for using a native SQL Server sequence, which was introduced in SQL Server 2012. It was something that application developers have been waiting for and Microsoft finally delivered.
The issue with using ##identity or scope_identity is that you actually have to write rows to some table before you can even contemplate doing something.
This makes it a bit more costly and messier than what it may need to be. In the case of using a sequence, you can issue a new sequence number and then decide what to do and once you decide what to do you're still guaranteed that you're the only one with that sequence number.
You would create a sequence like this. You should check out the documentation as well.
create sequence dbo.StudentIdSeq
as int -- this can be any integer type
start with 1 -- you can start with any valid number in the int, even negative
increment by 1;
go
Then you issue new sequence numbers by doing this ...
select next value for StudentIdSeq;
It may still be good to create a stored procedure with an output parameter that you can call from C# (which is what I would do). In fact you may want to take it a step further, in the case that you have a bunch of sequences, and create a slick stored procedure that will get a new sequence based on the type that is being requested from the caller.
This code is supposed to save some values in textboxes to a specific row. The code runs just fine with no hiccups, but refuses to actually update the database no matter what I do.
try
{
using (var con = new OleDbConnection())
{
con.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\User\Desktop\esoft\gym\gym\bin\Debug\Clients.accdb;";
con.Open();
using (var com = new OleDbCommand())
{
com.Connection = con;
com.CommandText = "UPDATE gym SET BMI = #bmi and Health = #health and weight_change_to_healthy_bmi = #weight WHERE ID = #id";
com.Parameters.AddWithValue("#bmi", bmi.Text);
com.Parameters.AddWithValue("#health", health.Text);
com.Parameters.AddWithValue("#weight", change.Text);
com.Parameters.AddWithValue("#id", id.Text);
com.ExecuteNonQuery();
}
}
MessageBox.Show("Saved");
}
catch (Exception ex)
{
MessageBox.Show("Not saved: " + ex.Message);
}
Any help would be much appreciated.
As Alex mentioned, SET part needs , instead of AND for multiple columns.
Check UPDATE syntax1;
UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value;
But I wanna say a few things more;
Don't use AddWithValue as much as you can. It may generate unexpected and surprising results sometimes. Use Add method overload to specify your parameter type and it's size.
Open your connection just before you execute your command. That means, you should open your connection just before your ExecuteNonQuery line.
Based on it's name, ID column should be some numeric value instead of character. Consider to change it's type or consider to change it's column name that refers some character typed column name.
1: I know I know.. a w3school link