Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use $action of the MERGE statement in output variable of stored procedure?

I have a stored procedure that either updates existing or inserts single record (I use MERGE TOP(1) ..) using MERGE statement in SQL Server 2008 R2. I use MERGE's OUTPUT clause to emit the value of $action to see what action was taken (INSERT, UPDATE, DELETE, 'blank').

However, when I call my SP from C# program, I am forced to execute a reader (DbCommand.ExecuteReader()) and loop through it once to get the $action value...

My question is, can the OUTPUT $action somehow be attached to SP output parameter which will enable me to do just DbCmmand.ExecuteNonQuery() and examine the output parameter? This will save me from having to instantiate the reader...

BTW, I am doing this call in a loop, so not having to instantiate the reader would be a bit faster (I hope)

like image 622
zam6ak Avatar asked Jan 20 '11 19:01

zam6ak


People also ask

Which of the following rules of using SQL MERGE is not applicable?

We cannot use WHEN NOT MATCHED BY SOURCE clause more than two times. If WHEN NOT MATCHED BY SOURCE clause in SQL Server MERGE statement was specified two times, one must use an update operation and another one must use delete operation.

Can we use where clause with MERGE?

The MERGE statement doesn't have a WHERE clause.

What is the use of MERGE statement in SQL?

The MERGE statement combines INSERT, UPDATE, and DELETE operations into a single statement, eliminating the need to write separate logic for each. It changes the data in a target table based on the data in a source table.

Can we use DELETE in MERGE statement?

Instead of writing a subquery in the WHERE clause, you can use the MERGE statement to join rows from a source tables and a target table, and then delete from the target the rows that match the join condition.


1 Answers

Sample table for discussion

create table t1 (id int identity primary key, other int);
insert t1 select 2;

This TSQL does a final select at the end, which will end up as the result for ExecuteNonQuery

set nocount on
declare @tmp table (action sysname)
;
with new(id,other) as (select 1,4)
merge top(1)
into t1
using new
on t1.id = new.id
when matched then update set other = new.id
when not matched then insert values (other)
output $action
into @tmp
;
set nocount off
select action from @tmp

This works well for TOP(1) since it produces only one row in @tmp, but the example below shows what happens when there are multiple records, continuing from the above

set nocount on
declare @tmp table (action sysname)
;
merge
into t1
using (values(1,4),(2,5)) new(id,other)
on t1.id = new.id
when matched then update set other = new.id
when not matched then insert values (other)
output $action
into @tmp
;
set nocount off
select action from @tmp

Output:

action
======
UPDATE
INSERT
  • Does additional temp table variable and SELECT statement to SP have much impact on performance?

This would be negligible, you can ignore it.

  • Would I have to "wrap" the 2 in a transaction (my app is multi threaded)?

No. The insert into the @tmp is atomic, and the select is coming from a temp table that is specific to the session (nothing can interfere with it)

like image 191
RichardTheKiwi Avatar answered Nov 15 '22 05:11

RichardTheKiwi