zam*_*6ak 5 c# database sql-server ado.net
我有一个存储过程,它使用SQL Server 2008 R2 中的MERGE 语句更新现有记录或插入单个记录(我使用 MERGE TOP(1) ..)。我使用 MERGE 的 OUTPUT 子句来发出 $action 的值以查看采取了什么操作(插入、更新、删除、'空白')。
但是,当我从 C# 程序调用我的 SP 时,我被迫执行一个读取器 (DbCommand.ExecuteReader()) 并通过它循环一次以获取 $action 值...
我的问题是,OUTPUT $action 能否以某种方式附加到 SP 输出参数,这将使我能够只执行 DbCmmand.ExecuteNonQuery() 并检查输出参数?这将使我不必实例化阅读器...
顺便说一句,我正在循环中进行此调用,因此不必实例化读取器会更快一些(我希望)
供讨论的示例表
create table t1 (id int identity primary key, other int);
insert t1 select 2;
Run Code Online (Sandbox Code Playgroud)
这个 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
Run Code Online (Sandbox Code Playgroud)
这对 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
Run Code Online (Sandbox Code Playgroud)
输出:
action
======
UPDATE
INSERT
Run Code Online (Sandbox Code Playgroud)
这可以忽略不计,您可以忽略它。
不。插入@tmp 是原子的,并且选择来自特定于会话的临时表(没有任何东西可以干扰它)