Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

T-SQL Is it possible to do an Update / Insert with a single fast operation

Let's say I have a table and I want to insert a row. The new row's key may already match an existing row's key in the table, in which case I want to update the existing row. Or, it may not exist in the table, in which case the new row should be inserted.

What is the most efficient way to perform such an operation? I was thinking of first doing a SELECT (perhaps with EXISTS) to see if a particular key is present, followed by an UPDATE if present and an INSERT if not. You would probably need to keep an UPDLOCK and a HOLDLOCK for this combination of statements in order to avoid race conditions, as well. This seems overly complicated and inefficient.

I was wondering if there was a more efficient way to do this in SQL Server 2008R2.

like image 771
Michael Goldshteyn Avatar asked Nov 24 '11 16:11

Michael Goldshteyn


People also ask

Which is faster insert or update SQL?

Insert would be faster because in case of update you need to first search for the record that you are going to update and then perform the update.

How do you insert and update at the same time?

2 Answers. Show activity on this post. mysql_query("INSERT INTO `test` (`name`) VALUES ('Mark')"); $id = mysql_insert_id(); mysql_quey("UPDATE `test2` SET `test_id` = $id WHERE `name` = 'Mark'");


1 Answers

SQL Server 2008 and newer have a MERGE statement which does exactly that.

See the MSDN Books Online docs on MERGE for details.

Basically, you need four things:

  • a source (table or view or inline SELECT statement)
  • a target
  • a JOIN condition that links the two
  • statements for cases when there's a MATCH (rows exists in both source and target), NOT MATCHED (when row doesn't exist in the target yet) and so forth

So you basically define something like:

MERGE (targettable) AS t
USING (sourcetable) AS s
ON (JOIN condition between s and t)
WHEN MATCHED THEN
   UPDATE SET t.Col1 = s.Col1, t.Col2 = s.Col2 (etc.)
WHEN NOT MATCHED THEN
   INSERT(Col1, Col2, ..., ColN) VALUES(s.Col1, s.Col2, ......, s.ColN)

This is done as one statement and highly optimized by SQL Server.

like image 186
marc_s Avatar answered Nov 15 '22 10:11

marc_s