C# : SQL Server query issue - c#

I create a table in SQL Server Management Studio with this code:
CREATE TABLE contact(
ID INT IDENTITY NOT NULL,
FIRSTNAME VARCHAR(100),
LASTNAME VARCHAR(100)
)
and in C# I used this code:
SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE");
SqlDataAdapter sd = new SqlDataAdapter();
sd.InsertCommand = new SqlCommand("INSERT INTO contact VALUES(#ID, #FIRSTNAME, #LASTNAME)");
sd.InsertCommand.Parameters.Add("#ID", SqlDbType.Int).Value = textBox1.Text;
sd.InsertCommand.Parameters.Add("#FIRSTNAME", SqlDbType.VarChar).Value = textBox2.Text;
sd.InsertCommand.Parameters.Add("#LASTNAME", SqlDbType.VarChar).Value = textBox3.Text;
sc.Open();
sd.InsertCommand.ExecuteNonQuery();
sc.Close();
but when I add the values to the database I get the error:
"ExecuteNonQuery: Connection property has not been initialized"
and I fixed it by adding sc to my first insertcommand, but when I run the program I got another error :
An explicit value for the identity column in table 'contact' can only
be specified when a column list is used and IDENTITY_INSERT is ON.

Do it this way:
using(SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE"))
{
using(SqlCommand command = new SqlCommand())
{
command.CommandText = "INSERT INTO contact (FirstName, LastName) VALUES(#FIRSTNAME , #LASTNAME");
command.CommandType = CommandType.Text;
command.Connection = sc;
command.Parameters.AddWithValue("#FIRSTNAME", textBox2.Text);
command.Parameters.AddWithValue("#LASTNAME", textBox3.Text);
sc.Open();
command.ExecuteNonQuery();
}
}
Important things to note:
1) Set your table up to have the Id column as an identity column and set autoincrement to true. This will automatically generate a numeric id when you insert
2) You are trying to insert into an identity column - you can't actually do this unless you enable identity inserts. I wouldn't bother - just use an autoincrement column and let the database control the id generation step.
You can generate your table this way:
CREATE TABLE Contact
(
Id int PRIMARY KEY IDENTITY,
FirstName varchar(100),
LastName varchar(100)
)
to get an autoincrementing primary key.
3) You don't need the SqlDataAdapter.

You need to pass the connection you intend to use to the SqlCommand
InsertCommand = new SqlCommand("INSERT INTO contact VALUES(#ID , #FIRSTNAME , #LASTNAME)", sc);
You need to dispose of your Connection and command as well. The standard pattern for doing this is:
using (SqlConnection conn = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE")){
conn.Open();
using (SqlCommand command = new SqlCommand(sqlString, conn)){
//stuff...
command.ExecuteNonQuery();
}
}

There's no relation between SqlConnection and SqlDataAdapter.
In fact, you don't need SqlDataAdapter. You only need SqlConnection and SqlCommand, for which you must use the constructor overload that accepts a connection as well.

Since ID is an INT IDENTITY field, you shouldn't (and can't) insert values into it. But if you use your "generic" INSERT statement without explicitly specifying which columns to insert values into, your INSERT statement will attempt to insert data into all columns - including ID, which you cannot insert anything into.
The solution (which I recommend for use always) is to explicitly define which columns to insert values into:
INSERT INTO dbo.contact(FirstName, LastName) VALUES(#FIRSTNAME, #LASTNAME)
This also works if you need to change your table and add another column - your original statement will fail, since the table suddenly now would have four columns, but your statement would only provide three values. If you explicitly define which columns you want to provide values for, your statement is more robust and works better.
So your complete code should look like this:
using(SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE"))
using(SqlCommand cmdInsert = new SqlCommand("INSERT INTO dbo.Contact(FirstName, LastName) VALUES(#FIRSTNAME, #LASTNAME)", sc))
{
cmdInsert.Parameters.Add("#FIRSTNAME", SqlDbType.VarChar, 100).Value = textBox2.Text;
cmdInsert.Parameters.Add("#LASTNAME", SqlDbType.VarChar, 100).Value = textBox3.Text;
sc.Open();
cmdInsert.ExecuteNonQuery();
sc.Close();
}

You need sd.InsertCommand = new SqlCommand("INSERT INTO contact VALUES(#ID , #FIRSTNAME , #LASTNAME)", sc);

You can do either ways:
a. Set you connection object to the adapter's insertcommand connection:
sd.InsertCommand.Connection = sc;
Or
b. Pass your connection object while initializing insert command as below:
sd.InsertCommand =
new SqlCommand("INSERT INTO contact VALUES(#ID, #FIRSTNAME, #LASTNAME)", sc);

Related

insert value from TextBox into sql

I'm getting this error message: Cannot insert the value NULL into column 'id', table ''; column does not allow nulls. INSERT fails. thanks in advance
protected void AddItem(object sender, EventArgs e)
{
string insertCmd = "INSERT INTO Picture (Album, id) VALUES (#Album, #id)";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["strConn"].ConnectionString))
{
conn.Open();
SqlCommand myCommand = new SqlCommand(insertCmd, conn);
// Create parameters for the SqlCommand object
// initialize with input-form field values
myCommand.Parameters.AddWithValue("#Album", txtAlbum.Text);
myCommand.Parameters.Add("#id", SqlDbType.Int).Direction = ParameterDirection.Output;
myCommand.ExecuteNonQuery();
int id = (int)myCommand.Parameters["#id"].Value;
}
}
I suppose that ID is an IDENTITY column. Its value is generated automatically by the database engine and you want to know what value has been assigned to your record.
Then you should change your query to
string insertCmd = #"INSERT INTO Picture (Album) VALUES (#Album);
SELECT SCOPE_IDENTITY()";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["strConn"].ConnectionString))
{
conn.Open();
SqlCommand myCommand = new SqlCommand(insertCmd, conn);
myCommand.Parameters.AddWithValue("#Album", txtAlbum.Text);
int newID = Convert.ToInt32(myCommand.ExecuteScalar());
}
The query text now contains a second instruction SELECT SCOPE_IDENTITY() separated from the first command by a semicolon. SCOPE_IDENTITY returns the last IDENTITY value generated for you by the database engine in the current scope.
Now the command is run using the ExecuteScalar to get back the single value returned by the last statement present in the query text without using any output parameter
I would think that ID is identity. You don't have to add this value. I would try the following code and check the database if you get automatically an ID.
string insertCmd = "INSERT INTO Picture (Album) VALUES (#Album)";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["strConn"].ConnectionString))
{
conn.Open();
SqlCommand myCommand = new SqlCommand(insertCmd, conn);
// Create parameters for the SqlCommand object
// initialize with input-form field values
myCommand.Parameters.AddWithValue("#Album", txtAlbum.Text);
myCommand.ExecuteNonQuery();
}
I case you want to set the id yourself(withoud automatic increment from the db), you should change the schema of the database removing identity from ID as shown below:
I hope this helps
If you need to stay this column empty you can try to replace to ' '(blank). This will work if you column is not "Key"
Or try to use:
substitute a value when a null value is encountered
NVL( string1, replace_with )
You can do this using stored procedure. Below is the script for Create stored procedure.
CREATE PROCEDURE [dbo].[InsertIntoPicture]
#Album varchar(500)=null,
#id int=0 output
AS
BEGIN
insert INTO Picture(Album)VALUES(#Album)
SET #id=##IDENTITY
END
Below is the code for call stored procedure with C# .
string insertCmd = "InsertIntoPicture";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["strConn"].ConnectionString))
{
conn.Open();
SqlCommand myCommand = new SqlCommand(insertCmd, conn);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("#Album", txtAlbum.Text);
myCommand.Parameters.Add("#id", SqlDbType.Int).Direction = ParameterDirection.Output;
myCommand.ExecuteNonQuery();
int id = (int)myCommand.Parameters["#id"].Value;
}
Using above code you can insert a date from TextBox and also get last inserted record ID as an output variable as per your requirement.
Thanks .

Cannot insert value via SqlDataAdapter

I am learning how to work with SQL in C#, and I got in troubles with using SqlDataAdapter. I have tried to use direct queries via SqlCommand class and everything works fine, but when I rewrote my code to use SqlDataAdapter I have no changes in my table. There is my code:
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ADO"]
.ConnectionString);
connection.Open();
SqlDataAdapter daUser = new SqlDataAdapter("SELECT * FROM Books", connection);
SqlCommand insert = new SqlCommand();
insert.Connection = connection;
insert.CommandText = "INSERT INTO Books (name, author) VALUES (#name, #author);";
SqlParameterCollection pc = insert.Parameters;
pc.Add("#name", SqlDbType.VarChar, 20, "test123");
pc.Add("#author", SqlDbType.VarChar, 20, "test322");
daUser.InsertCommand = insert;
DataSet ds = new DataSet();
daUser.Fill(ds, "Books");
daUser.Update(ds, "Books");
Table Books was created with this SQL query in SQL Server Management Studio:
CREATE TABLE Books
(
id int PRIMARY KEY IDENTITY(1,1),
name varchar(MAX) NOT NULL,
author varchar(MAX) NOT NULL
)
INSERT INTO Books(name, author)
VALUES('1984', 'George Orwell'), ('Fathers and sons', 'Dostoevski')
Looks like I am missing something to do, that why my code have no effect on table.
SqlDataAdapter.Update will call its InsertCommand only for the rows of datatable having RowState = DataRowState.Added.
This rowstate is automatically assigned to the datarows being added to rows collection using DataTable.Add method (until next call to AcceptChanges method). Also you can use DataRow.SetAdded method to force this state assignment.
Since you're not modifying/adding anything in you datatable after you've populated it with select command, it has nothing to insert.
Change your code to something like
daUser.Fill(ds, "Books");
var newBook = daUser.Tables[0].NewRow();
newBook["name"] = "New Book";
newBook["author"] = "Author Name";
daUser.Tables[0].Rows.Add(newBook);
daUser.Update(ds, "Books");
and in this case it should be new row added to the database table.
See MSDN for reference.
Just to clarify the previous answer, which is correct, you want to call ExecuteNonQuery() on the command not the dataAdapter.
SqlCommand insert = new SqlCommand();
insert.Connection = connection;
insert.CommandText = "INSERT INTO Books (name, author) VALUES (#name,
#author);";
SqlParameterCollection pc = insert.Parameters;
pc.Add("#name", SqlDbType.VarChar, 20, "test123");
pc.Add("#author",
SqlDbType.VarChar, 20, "test322");
// you do not need this line if you execute the insert on the command object.
// daUser.InsertCommand = insert;
//Add this line instead:
insert.ExecuteNonQuery();
Joey

Update only one column using ID in asp.net

I want to update only one column in my table by ID .
I don't have any error but this don't work, it won't update. I have ID column and 7 more columns.
SqlCommand cmd1 = new SqlCommand("update table set amount=#kol where ID=#id" , con);
cmd1.Parameters.AddWithValue("#id", textbox1.Text);
cmd1.Parameters.AddWithValue("#kol", textbox2.Text );
Is your table named "table" or is that just for the example here?
Because otherwise you properbly need to change "table" to whatever table your're trying to update. or surround it with [] if it is actually called "table"
Can you please check that you have commited your work , if there is no exception then that will be the reason
and if not put setautocommit(true) - java version
you can find it for c#
please check whether table name is correct and the table which you are verifying is correct
please give some other table name than table for good practice
As long as you have con.Open and ExecuteNonQuery and have the username/password and connectionstring right your code will work.
This will work after you change the connectionstring, if not the problem is sql server.
private void UpdateTable()
{
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=YourDataBase;Persist Security Info=True;User ID=username;Password=pass");
SqlCommand cmd1 = new SqlCommand("update YourTable set amount=#kol where ID=#id", con);
cmd1.Parameters.AddWithValue("#id", textBox1.Text);
cmd1.Parameters.AddWithValue("#kol", textBox2.Text);
con.Open();
cmd1.ExecuteNonQuery();
}

OleDbDataAdapter Update To dbf [Free Table] -Syntax Error()

When I insert through the OleDbCommand with direct values no problem, it's working fine
OleDbCommand OleCmd1 = new OleDbCommand("Insert into My_Diary (sl_no,reminder) values("+a1+",'CHECK VALUE')", OleCon1);
OleCmd1->ExecuteNonQuery();
But when I like to update through parameter its showing "Syntax Error"....I can't identify my mistake...
string MyConStr = "Provider=VFPOLEDB.1; Data Source='C:\\For_Dbf'; Persist Security Info=False";
InsSavDiaryCmd = "Insert into My_Table1 (sl_no,reminder) values (#sl_no,#reminder) ";
VFPDAp=gcnew OleDbDataAdapter();
VFPDApMy_Table1InsertCommand = gcnew OleDbCommand(InsSavDiaryCmd, OleCon1);
WithInsVar = VFPDAp.InsertCommand.Parameters;
WithInsVar.Add("#sl_no", OleDbType.Integer, 10, "sl_no");
WithInsVar.Add("#reminder", OleDbType.Char, 250, "reminder");
OleCon1.ConnectionString = MyConStr;
OleCon1.Open();
OleDbTransaction Trans=OleCon1.BeginTransaction();
//VFPDAp.DeleteCommand.Transaction = Trans;
//VFPDAp.UpdateCommand.Transaction = Trans;
VFPDAp.InsertCommand.Transaction = Trans;
VFPDAp.Update(MyDataTbl);
Trans.Commit();
OleCon1.Close();
The OleDbCommand doesn't use named parameters. You need to change the insert statement so that it uses questions.
InsSavDiaryCmd = "Insert into My_Table1 (sl_no,reminder) values (?, ?) ";
You need to make sure that you have a parameter for each question mark and make sure that the parameters are inserted in order of their use in the insert statement.
** If you'd like to use name parameters... you can try using VfpClient which is a project that I'm working on to make data access a little nicer from .Net.

'Invalid object name' for temporary table when using command with parameters

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.

Categories