views:

163

answers:

3

Is there a SQL Server 2000 functional equivalent to MySQL's ON DUPLICAT KEY clause? This Answer led me to look at the Instead of Trigger construct, but the sample looks clunky, and the functionality would be hidden in the trigger, and not be directly in the stored proc.

FWIW: I am trying to create a stats table for per-minute summaries, so that I can just call one Procedure to log the fact that an action happened and increment the counter for the appropriate minute.

+1  A: 

upsert

http://en.wikipedia.org/wiki/Upsert

INSERT ... WHERE NOT EXISTS (SELECT 1 FROM table WHERE id = ?)

merge

but i think is only in SQL 2003

MERGE INTO table_name USING table_name ON (condition)
  WHEN MATCHED THEN
  UPDATE SET column1 = value1 [, column2 = value2 ...]
  WHEN NOT MATCHED THEN
  INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...])

http://en.wikipedia.org/wiki/Merge_(SQL)

Haim Evgi
`MERGE` is SQL Server 2008+ : http://technet.microsoft.com/en-us/library/bb510625.aspx
OMG Ponies
according to wiki its in 2003 (the link that i put in the answer) :"It was officially introduced in the SQL:2003 standard"
Haim Evgi
I can't get the syntax for the upsert example to work in SQL 2000. Should it be able to work there?
My Other Me
The "SQL 2003 **standard** " is quite a different thing from SQL Server 2008.
Emtucifor
+1  A: 

Also clunky, but you could do this in your procedure:

insert ... where not exists (...);

update ....;

knowing that your insert will fire when the data is new, and your update only when the data exists.

davek
Is that atomic enough that I could run it from several threads? Should I then insert a 0 count and always call the insert and the update?
My Other Me
Does this work in SQL Server 2000?
My Other Me
+2  A: 

I use this:

begin tran;

update ... where ... ;

if @@rowcount = 0
  insert ...
commit tran;

As I understand it, with proper indices in place, the update places proper range locks that would prevent others from inserting same thing concurrently.

GSerg