【问题标题】:Is it possible to use $action of the MERGE statement in output variable of stored procedure?是否可以在存储过程的输出变量中使用 MERGE 语句的 $action?
【发布时间】:2011-01-20 19:06:24
【问题描述】:

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

但是,当我从 C# 程序调用我的 SP 时,我不得不执行一个读取器 (DbCommand.ExecuteReader()) 并循环一次以获取 $action 值...

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

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

【问题讨论】:

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


    【解决方案1】:

    供讨论的示例表

    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 的插入是原子的,选择来自特定于会话的临时表(没有任何东西可以干扰它)

    【讨论】:

    • 在上面对@gbn 的评论中查看我的问题
    【解决方案2】:

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

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

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

    【讨论】:

    • 我不会将一张桌子与另一张桌子合并。我正在从 CSV 文件中读取记录并将它们传递给我的 SP。循环的原因是 b/c 我需要能够将其他业务逻辑(来自不同的 DLL)应用到“现场”记录......
    【解决方案3】:

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

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

    【讨论】:

    • 这将要求 SP 具有 MERGE 和 SELECT(2 个语句)...您知道向 SP 添加额外的临时表变量和 SELECT 语句是否对性能有很大影响吗?我是否必须在事务中“包装” 2(我的应用程序是多线程的)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多