【问题标题】:Counting the number of deleted rows in a SQL Server stored procedure计算 SQL Server 存储过程中删除的行数
【发布时间】:2010-09-15 12:08:57
【问题描述】:

在 SQL Server 2005 中,有没有一种方法可以删除行并被告知实际上删除了多少行?

我可以在相同条件下执行select count(*),但我需要它完全值得信赖。

我的第一个猜测是使用 @@ROWCOUNT 变量 - 但没有设置,例如

delete 
from mytable 
where datefield = '5-Oct-2008' 

select @@ROWCOUNT 

总是返回 0。

MSDN 建议使用 OUTPUT 构造,例如

delete from mytable 
where datefield = '5-Oct-2008' 
output datefield into #doomed

select count(*) 
from #doomed

这实际上因语法错误而失败。

有什么想法吗?

【问题讨论】:

    标签: sql-server tsql audit sql-delete


    【解决方案1】:

    你试过SET NOCOUNT OFF吗?

    【讨论】:

    • 我曾以为我已经尝试过这个 - 但显然我没有尝试过,因为它很有魅力 - 谢谢。
    • MSDN 似乎说 SET NOCOUNT 会影响打印输出。为什么这会影响@@ROWCOUNT?它不应该总是返回删除的行数(在 OP 中)吗?
    • *** 这是猜想 *** 我认为这是因为设置 NOCOUNT 会告诉系统它不必跟踪计数以提高效率
    【解决方案2】:

    我在 SQL2000 中将@@ROWCOUNT 用于此目的,没有任何问题。确保在检查之前不会无意中重置此计数(BOL:'此变量被任何不返回行的语句设置为 0,例如 IF 语句')。

    【讨论】:

      【解决方案3】:

      这样做:

      SET NOCOUNT off ;
      SELECT @p1 = @@ROWCOUNT
      

      其中 p1 是您在存储过程中设置的输出参数。 希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        在您的示例中,@@ROWCOUNT 应该可以工作 - 这是找出已删除行数的正确方法。如果您尝试从应用程序中删除某些内容,则需要使用 SET NOCOUNT ON

        根据MSDN@@ROWCOUNT 函数即使在 SET NOCOUNT 为 ON 时也会更新,因为SET NOCOUNT 只会影响执行后您收到的消息。

        因此,如果您尝试使用来自例如 ADO.NET 的 @@ROWCOUNT 的结果,那么 SET NOCOUNT ON 肯定会有所帮助。

        【讨论】:

          【解决方案5】:

          我发现了一个您不能使用@@rowcount 的情况,例如当您想知道已删除值的不同计数而不是总计数时。在这种情况下,您必须执行以下操作:

          delete from mytable 
          where datefield = '5-Oct-2008' 
          output deleted.datefield into #doomed
          
          select count(distinct datefield)
          from #doomed
          

          OP 中的语法错误是因为outputdatefield 字段名称之前没有包含deleted

          【讨论】:

            【解决方案6】:

            出于好奇,您如何调用该过程? (我假设它是一个存储过程?)。我问的原因是存储过程的返回值(在本例中为 0)和行集结果之间存在差异——在本例中为单行和单列。在 ADO.Net 中,前者将通过参数访问,而后者通过 SqlDataReader 访问。您是否可能将过程的返回值误认为是行数?

            【讨论】:

            • 这是一个地方的代码(但是是的,在一个存储过程中) - 我正在删除一些数据,然后将该事实写入状态表,所以这并不是真正被混淆的情况超过返回值。
            【解决方案7】:

            创建一列id的临时表。

            插入临时表,选择要删除的 ID。这让你数数。

            从 id 所在的表中删除(从临时表中选择 id)

            【讨论】:

            • 虽然可行,但这样的开销是浪费。
            • 这确实会带来很差的性能,查询将花费至少 2 倍的时间,如果您要处理大量记录,这可能是相当长的时间。创意思维!
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-15
            • 2016-09-30
            • 2015-02-26
            相关资源
            最近更新 更多