INSERT vs. UPDATE [duplicate] - c#

This question already has answers here:
If Exists Update Else Insert with VB.net (sql parameterised query)
(3 answers)
Closed 9 years ago.
I have the following query:
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["chestionar"].ConnectionString);
SqlCommand cmd = new SqlCommand("INSERT INTO Raspunsuri Values(#raspuns,#cnp,#data,'1',#ip,#idsesiune)", con);
cmd.Parameters.AddWithValue("#cnp", Session["sesiune_cnp"]);
cmd.Parameters.AddWithValue("#raspuns", textbox1.Text);
cmd.Parameters.AddWithValue("#data", DateTime.Now.ToLocalTime());
cmd.Parameters.AddWithValue("#ip",ip);
cmd.Parameters.AddWithValue("#idsesiune", id_sesiune);
try
{
con.Open();
cmd.ExecuteNonQuery();
Response.Redirect("User2.aspx");
}
catch (Exception ex)
{
Console.WriteLine("Error:" + ex);
}
finally
{
con.Close();
}
What i need is to see if there is any record in the table and if there is than update else insert it.How can I achieve that?

This is probably best done in a Stored Procedure due to the amount of scripting involved (it would be messy inline!).
Pass your parameters to a Stored Procedure and do something like:
IF EXISTS(SELECT cnp FROM Raspunsuri WHERE cnp=#cnp)
BEGIN
UPDATE ...
WHERE cnp=#cnp
END
ELSE
BEGIN
INSERT INTO....
END
Assuming #cnp is your Primary Key
Your SqlCommand would then be changed to:
SqlCommand cmd = new SqlCommand("sp_StoredProcedureName", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#cnp", Session["sesiune_cnp"]);
cmd.Parameters.AddWithValue("#raspuns", textbox1.Text);
cmd.Parameters.AddWithValue("#data", DateTime.Now.ToLocalTime());
cmd.Parameters.AddWithValue("#ip",ip);
cmd.Parameters.AddWithValue("#idsesiune", id_sesiune);

You can use the Exists function in SQL. For Example
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["chestionar"].ConnectionString);
SqlCommand cmd = new SqlCommand("if Exists(Select 1 from Raspunsuri where <your unique criteria>)\r\n" +
"Update Raspunsuri set <values you want to set> where <your unique criteria\r\n" +
"else\r\n" +
"INSERT INTO Raspunsuri Values(#raspuns,#cnp,#data,'1',#ip,#idsesiune)", con);
cmd.Parameters.AddWithValue("#cnp", Session["sesiune_cnp"]);
cmd.Parameters.AddWithValue("#raspuns", textbox1.Text);
cmd.Parameters.AddWithValue("#data", DateTime.Now.ToLocalTime());
cmd.Parameters.AddWithValue("#ip",ip);
cmd.Parameters.AddWithValue("#idsesiune", id_sesiune);
That should do the trick

You can use the ##ROWCOUNT feature from SQL Server.
UPDATE Raspunsuri SET (...) WHERE PrimaryKeyColumn='YourValue'
IF ##ROWCOUNT=0
INSERT INTO Raspunsuri VALUES (...)
Similar question: Insert / Update to Sql

What i need is to see if there is any record in the table and if there is than update else insert
it.How can I achieve that?
Write proper SQL?
Basiacll waht you need to forumlate is known as an "Upsert".
http://www.databasejournal.com/features/mssql/article.php/3739131/UPSERT-Functionality-in-SQL-Server-2008.htm
hasa good explanation.

First you check whether the record is present in the table by writing a query as "Select count(*) from tablename where columnvalue="something".If count is more than 0 then table has record.So in that case you write an Update statement else write Insert statement. This you can write in your code or by writing a stored procedure.

What i need is to see if there is any record in the table and if there
is than update else insert it.How can I achieve that?
I like #Alex's approach
-- For each row in source
BEGIN TRAN
UPDATE target
SET <target_columns> = <source_values>
WHERE <target_expression>
IF (##ROWCOUNT = 0)
INSERT target (<target_columns>)
VALUES (<source_values>)
COMMIT

Related

How to combine multiple SQL Commands into one?

Is it possible to optimize the following queries by merging them inside a single SQLCommand?
SqlCommand cmd = new SqlCommand
{
CommandType = CommandType.Text,
CommandText = "DELETE FROM cbu_naslovi WHERE [ID]='" + CurrentID + "'",
Connection = con
};
SqlCommand cmd1 = new SqlCommand
{
CommandType = CommandType.Text,
CommandText = "DELETE FROM cbu_deli WHERE [IDX]='" + CurrentID + "'",
Connection = con
};
cmd.ExecuteNonQuery();
cmd1.ExecuteNonQuery();
EDIT: Working solution, as suggested by the community answers bellow
SqlCommand cmd = new SqlCommand
{
CommandType = CommandType.Text,
CommandText = "DELETE FROM cbu_naslovi WHERE [ID] = #CurrentID; DELETE FROM cbu_deli WHERE [IDX] = #CurrentID",
Connection = con
};
cmd.Parameters.AddWithValue("#CurrentID", CurrentID);
cmd.ExecuteNonQuery();
Yes, you can just separate them with a semicolon. For example I have code that executes the following in a single call
SET NOCOUNT ON;
DECLARE #decimalDate DECIMAL(12,0);
DECLARE #charDate CHAR(12);
DECLARE #utcDate DATETIMEOFFSET;
DECLARE date_cursor CURSOR FOR SELECT {1} FROM {0} WHERE ISNULL({1},0)!=0;
OPEN date_cursor;
FETCH NEXT FROM date_cursor INTO #decimalDate;
WHILE ##FETCH_STATUS=0
BEGIN
BEGIN TRY SET #charDate=CONVERT(CHAR(12),#decimalDate);
SET #utcDate=SwitchOffset(
CONVERT(DATETIME,'20'
+SUBSTRING(#charDate,1,2)+'-'+SUBSTRING(#charDate,3,2)+'-'
+SUBSTRING(#charDate,5,2)+' '+SUBSTRING(#charDate,7,2)+':'
+SUBSTRING(#charDate,9,2)+':'+SUBSTRING(#charDate,11,2)
,121) AT TIME ZONE '{3}',0);
END
TRY BEGIN CATCH
SET #utcDate=SysUtcDateTime();
END CATCH;
BEGIN
TRY UPDATE {0} SET {2}=#utcDate WHERE CURRENT OF date_cursor;
END TRY
BEGIN CATCH END CATCH;
FETCH NEXT FROM date_cursor INTO #decimalDate;
END;
CLOSE date_cursor;
DEALLOCATE date_cursor;
There are exceptions. For instance the "create procedure" statement must be the first statement of a block. But most DML can be batched like this.
You can write it like this:
SqlCommand cmd = new SqlCommand
{
CommandType = CommandType.Text,
CommandText = $"DELETE FROM cbu_naslovi WHERE [ID]='{CurrentID}';DELETE FROM cbu_deli WHERE [IDX]='{CurrentID}'",
Connection = con
};
if you need to run Non Query operation, you could try to execute bunch of commands by using Server object.
benefit: you could use GO in SQL statement. Command does not allow to use GO.
server.ConnectionContext.ExecuteNonQuery("your SQL statement -- could be 100 statements with hundrends of GO commands", ExecutionTypes.Default)
server variable has type Server

SQL CE how to prevent duplicate insert

SqlCeCommand command = new SqlCeCommand(#"INSERT INTO fpl_table
(FLIGHT_ID, BPN_TIME, BPX_TIME, DAY_NB)
VALUES (#FLIGHT_ID, #BPN_TIME, #BPX_TIME, #DAY_NB)
ON DUBLICATE UPDATE FLIGHT_ID = #FLIGHT_ID, BPN_TIME=#BPN_TIME,BPX_TIME=#BPX_TIME,DAY_NB=#DAY_NB"
,connection);
command.Parameters.AddWithValue("FLIGHT_ID", format);
command.Parameters.AddWithValue("BPN_TIME", format1);
command.Parameters.AddWithValue("BPX_TIME", format2);
command.Parameters.AddWithValue("DAY_NB", format3);
Hi everyone!
Ive got the problem with inserting 4 values into columns. I wanna prevent inserting 4 existing columns into database, i cant set them unique, cause the same column can be inserted with other 1,2 or 3 columns, i just wanna prevent only 4 existing columns insert.
you can add a unique constraint on 4 columns
CONSTRAINT UC_unique UNIQUE (col1, col2, col3, col4)
https://www.w3schools.com/sql/sql_unique.asp
Why not you use a seperate function to find out duplicate records at first.
bool CheckDuplicateFlight(int FLIGHT_ID)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = #"YOURCONNECTION STRING";
con.Open();
if (con.State == System.Data.ConnectionState.Open)
{
SqlCeCommand cmd = new SqlCeCommand("select count(*) from YOURTABLE where FLIGHT_ID= #FLIGHT_ID", con);
cmd.Connection = con;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Parameters.AddWithValue("#FLIGHT_ID",FLIGHT_ID);
int ExistingId= Convert.ToInt32(cmd.ExecuteScalar());
}
con.Close();
if(ExistingId> 0)
return true;
return false;
}
if(CheckDuplicateFlight(FLIGHT_ID))
{
///// Your insertion/Update Code here
}
But Your Question is confusing a bit, Are you sure you want to insert record instead of update??? Insert query always inserts new record.
You need to add Unique Constraints to 3 columns, and than using exception handling at your code, insert new record.

How to store multiple rows in single button click using stored procedure

In the database I created a stored procedure
ALTER procedure [dbo].[usercusdet_pro](#user varchar(25),#cusname varchar(max))--,#cnt int)
as
begin
--declare #count int
--set #count=0
--if(#count<#cnt)
insert usercusdet values(#user,#cusname)
end
to insert values. When I click the button, multiple rows should be inserted in the table.
int cnt = gvTranferRows.Rows.Count;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["gdb"].ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("usercusdet_pro", con);
cmd.CommandType = CommandType.StoredProcedure;
if (con.State == ConnectionState.Closed)
con.Open();
for (int i=0;i<cnt;i++)
{
cmd.Parameters.Add("#user", SqlDbType.VarChar).Value = "A001";
cmd.Parameters.AddWithValue("#cusname",gvTranferRows.Rows[i].Cells[0].Text);
//cmd.Parameters.AddWithValue("#cnt", cnt);
cmd.ExecuteNonQuery();
}
When I try to add value it shows an error:
procedure or function has too many arguments specified
What's the cause of this error?
You need to clear the parameters before the next iteration i.e.
cmd.Parameters.Add("#user", SqlDbType.VarChar).Value = "A001";
cmd.Parameters.AddWithValue("#cusname",gvTranferRows.Rows[i].Cells[0].Text);
//cmd.Parameters.AddWithValue("#cnt", cnt);
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
Or given the #user parameter is fixed, you just need to replace the #cusname one
cmd.Parameters.Add("#user", SqlDbType.VarChar).Value = "A001";
for (int i=0;i<cnt;i++)
{
cmd.Parameters.AddWithValue("#cusname",gvTranferRows.Rows[i].Cells[0].Text);
cmd.ExecuteNonQuery();
cmd.Parameters.RemoveAt("#cusname");
}
You can use Table valued parameter starting sql server 2008 onwards.
OR
Youc an go for passing data as XML if using version prior to SQL Server 2008.
OR
Not a good apporach but you can use delimiter seperated string as well.

" Error in connection" when use insert command to access db with ado.net C#

I write code to insert some values to access database with C#/ado.net but there is an error appear called "error in connection" although i use select command to retrieve some valuesin the same program and works successfully
OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Mohamed\documents\visual studio 2012\Projects\Library Store\Library Store\Book.accdb");
conn.Open();
OleDbCommand cmd = new OleDbCommand("INSERT INTO Store VALUES (#val1,#val2,#val3,#val4,#val5,#val6)", conn);
cmd.Parameters.AddWithValue("#val1", ISBNTB.Text.Trim());
cmd.Parameters.AddWithValue("#val2", NameTB.Text.Trim());
cmd.Parameters.AddWithValue("#val3", GategoryTB.Text.Trim());
cmd.Parameters.AddWithValue("#val4", AuthorTB.Text.Trim());
cmd.Parameters.AddWithValue("#val5", int.Parse(CostTB.Text.Trim()));
cmd.Parameters.AddWithValue("#val6", dateTimePicker1.Text);
cmd.ExecuteNonQuery();
MessageBox.Show(" Done :)");
conn.Close();
thanks;
Give this a shot, you didn't specify what error it was but this should help you out if anythign figure out if you really have all columns your trying to insert to
Try writing you sql statement like so
INSERT INTO Table ( Column1, Column2 ) VALUES
( Value1, Value2 ), ( Value1, Value2 )
OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Mohamed\documents\visual studio 2012\Projects\Library Store\Library Store\Book.accdb");
conn.Open();
OleDbCommand cmd = new OleDbCommand("INSERT INTO Store **( Column1, Column2 )** VALUES(#val1,#val2,#val3,#val4,#val5,#val6)", conn);
cmd.Parameters.AddWithValue("#val1", ISBNTB.Text.Trim());
cmd.Parameters.AddWithValue("#val2", NameTB.Text.Trim());
cmd.Parameters.AddWithValue("#val3", GategoryTB.Text.Trim());
cmd.Parameters.AddWithValue("#val4", AuthorTB.Text.Trim());
cmd.Parameters.AddWithValue("#val5", int.Parse(CostTB.Text.Trim()));
cmd.Parameters.AddWithValue("#val6", dateTimePicker1.Text);
cmd.ExecuteNonQuery();
MessageBox.Show(" Done :)");
conn.Close();
You need to specify the column names in your insert statement so that the DB knows where the data is going.
"INSERT INTO Store (Column1, Column2) VALUES (#val1, #val2)"
If you insert value to database with all column you can use this query
INSERT INTO Store VALUES(#val1,#val2,#val3,#val4,#val5,#val6)
If you insert value to database with few column you will get this error, and you must write it as
INSERT INTO Store **( Column1, Column2 )** VALUES(#val1,#val2,#val3,#val4,#val5,#val6)

SQL INSERT INTO statement with WHERE Statement

Can you use a WHERE statement within an INSERT INTO statement in SQL?
here is what i am currently trying to do.
INSERT INTO AssetComponents(ComponentID, ComponentDescription)
VALUES (#ComponentType, #CompDescr)
WHERE (AssetTagNumber = #TagNo)
But the compiler is having an issue with the WHERE statement.
thanks
***UPDATE****
This is the full code that i am using so far with amendments
protected void AddBut_Click(object sender, EventArgs e)
{
//still passing the Asset tag number forward here
var ID = Request.QueryString["Id"];
string sql = "";
using (SqlConnection con = new SqlConnection("Data Source: *******************)
{
sql = "IF (AssetTagNumber = #TagNo) " +
"BEGIN " +
"INSERT INTO AssetComponents(ComponentID, ComponentDescription) " +
"VALUES (#ComponentType, #CompDescr) " +
"END ";
using (SqlCommand cmd = new SqlCommand(sql, con))
{
// try
// {
cmd.Parameters.AddWithValue("#TagNo", ID);
cmd.Parameters.AddWithValue("#ComponentType", TypeDDL.Text.Trim());
cmd.Parameters.AddWithValue("#CompDescr", DescrTB.Text.Trim());
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Response.Redirect("ComponentDetails.aspx");
// }
// catch (SqlException ex) { MessageBox.Show(" "); }
// catch (Exception ex) { MessageBox.Show(" "); }
}
}
}
Im sorry i was not clear enough first time around.
What i want to do is insert a new record with a clause that says if this record has an existing PK then use this key to insert another entry for that record
Apologies once again
Why don't you just use IF-clause?
IF (AssetTagNumber = #TagNo)
BEGIN
INSERT INTO AssetComponents(ComponentID, ComponentDescription)
VALUES (#ComponentType, #CompDescr)
END
For statements with WHERE script should look similar to:
INSERT INTO AssetComponents(ComponentID, ComponentDescription)
SELECT #ComponentType, #CompDescr
FROM <table>
WHERE (AssetTagNumber = #TagNo)
You can not "conditionally insert" like that. The WHERE clause is only available for SELECT, UPDATE or DELETE.
To check whether you need to INSERT a new record, you need to use IF, as in:
IF NOT EXISTS (SELECT ...)
INSERT INTO ...
if EXISTS (select * from AssetComponents where AssetTagNumber = #TagNo)
Begin
INSERT INTO AssetComponents(ComponentID, ComponentDescription)
(#ComponentType, #CompDescr)
End
Use this:
UPDATE AssetComponents
Set ComponentID=#ComponentType, ComponentDescription=#CompDesc
Where AssetTagNumber = #TagNo
WHERE clause is something that helps to filter record, so it preferably uses with either SELECT or UPDATE. For INSERT we normally use IF NOT EXISTS clause.
See Examples:
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/724ab6f3-413f-4c59-9b68-776f3ecfa899/insert-if-not-exists-into
http://msdn.microsoft.com/en-us/library/ms174335.aspx
Also, after looking at documentation, we can see that INSERT statement has NO support for WHERE clause.
If records already exists you can perform eith UPDATE or DELETE with INSERT operations.
You can try like:
IF NOT EXISTS (SELECT * FROM AssetComponents WHERE (AssetTagNumber = #TagNo))
INSERT INTO AssetComponents(ComponentID, ComponentDescription) VALUES (#ComponentType, #CompDescr)
ELSE
--UPDATE fields
Consider INSERT SELECT:
INSERT INTO AssetComponents(ComponentID, ComponentDescription)
SELECT [fill out here] AS ComponentID,
[fill out here] AS ComponentDescription
FROM somesource
WHERE [condition]
This is a specialty of MS SQL Server so will not work in other databases. It sort of requires that your data are already in another table or other source that you can query.

Categories