我有一个存储过程可以在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()并检查输出参数? 这将使我免于必须实例化读者...
顺便说一句,我正在循环中进行此调用,因此不必实例化读取器会更快(我希望)答案 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
这可以忽略不计,你可以忽略它。
没有。 @tmp中的插入是原子的,而select来自特定于会话的临时表(没有任何东西可以干扰它)
答案 1 :(得分:2)
您可以将值输出到变量并使该变量成为输出变量。这当然只有在一次且只有一个值可变的情况下才有效,但听起来这是你的情况。
另一方面,您可以输出到变量表,然后选择表变量中的记录作为过程的一部分。
你为什么这样做是循环?使用表变量作为输入变量(如果有的话)一次处理所有记录可能要快得多,并使用基于集合而不是逐个记录(也称为逐行记录)行)处理。
答案 2 :(得分:2)
您可以将OUTPUT分流到表变量中,然后从中分配标量输出参数。
您不能直接将OUTPUT行分配给标量变量。