是否可以在存储过程的输出变量中使用MERGE语句的$ action?

时间:2011-01-20 19:06:24

标签: c# sql-server database ado.net

我有一个存储过程可以在SQL Server 2008 R2中使用MERGE statement更新现有或插入单个记录(我使用MERGE TOP(1)..)。我使用MERGE的OUTPUT子句发出$ action的值来查看采取了什么操作(INSERT,UPDATE,DELETE,'blank')。

然而,当我从C#程序调用我的SP时,我被迫执行一个阅读器(DbCommand.ExecuteReader())并循环一次以获得$ action值...

我的问题是,OUTPUT $动作能否以某种方式附加到SP输出参数,这将使我能够只执行DbCmmand.ExecuteNonQuery()并检查输出参数? 这将使我免于必须实例化读者...

顺便说一句,我正在循环中进行此调用,因此不必实例化读取器会更快(我希望)

3 个答案:

答案 0 :(得分:4)

供讨论的样本表

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

此TSQL在最后进行最终选择,最终将作为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

这适用于TOP(1),因为它在@tmp中只生成一行,但下面的示例显示了当有多个记录时会发生什么,从上面继续

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

输出:

action
======
UPDATE
INSERT
  • SP的附加临时表变量和SELECT语句是否会对性能产生很大影响?

这可以忽略不计,你可以忽略它。

  • 我是否必须在事务中“包装”2(我的应用程序是多线程的)?

没有。 @tmp中的插入是原子的,而select来自特定于会话的临时表(没有任何东西可以干扰它)

答案 1 :(得分:2)

您可以将值输出到变量并使该变量成为输出变量。这当然只有在一次且只有一个值可变的情况下才有效,但听起来这是你的情况。

另一方面,您可以输出到变量表,然后选择表变量中的记录作为过程的一部分。

你为什么这样做是循环?使用表变量作为输入变量(如果有的话)一次处理所有记录可能要快得多,并使用基于集合而不是逐个记录(也称为逐行记录)行)处理。

答案 2 :(得分:2)

您可以将OUTPUT分流到表变量中,然后从中分配标量输出参数。

您不能直接将OUTPUT行分配给标量变量。

相关问题