【问题标题】:When a SQL job starts, what is the value of @@ROWCOUNT?当 SQL 作业启动时,@@ROWCOUNT 的值是多少?
【发布时间】:2017-01-03 18:33:48
【问题描述】:

我一直在寻找这个问题的答案,但我相信这对其他人也可能是有用的信息。

我在 SQL Server Management Studio 中使用 TSQL。由于我们的系统处理信息的方式,最好以较小的批次进行更新。我们使用的一个技巧是将更新包装在一个 while 循环中:

while (@@Rowcount <> 0)
begin
    update top (800) etc etc
end

我创建了一个作业来定期进行此更新,虽然这在查询窗口中有效,但它似乎不适用于作业。作业开始时是否填充行计数值?

【问题讨论】:

  • 如果你想让@@ROWCOUNT不为0,就在循环之前加上SELECT 1;
  • 零作为@@ROWCOUNT 的初始值对我来说很有意义。我认为它在 SQL Server Management Studio 中工作的原因是因为 Management Studio 在执行在查询窗口中输入的内容之前在同一连接上发出了一堆命令。当然修复它应该是直截了当的,只需按照 DVT 的建议选择一些常量。
  • WHILE 1 = 1 BEGIN; UPDATE ...; IF @@ROWCOUNT = 0 BREAK; END。因为@@ROWCOUNT 在你放屁时(隐喻地)会重置,所以最好只在声明之后立即使用它,而不是在你没有发布之前使用它。顺便说一句,WHILE 1 = 1 ... BREAK 构造在您使用游标时也能很好地工作(以避免重复 FETCH 语句)。

标签: sql-server tsql ssms jobs rowcount


【解决方案1】:

@@ROWCOUNT 在语句开头为 0,对您来说,当 SSMS 第一次打开连接时,它会在后台执行一系列查询(您可以通过跟踪捕获特定查询),所以你得到的 @@ROWCOUNT 的残值为 1。

在进行这样的批量更新时,我倾向于采用稍微不同的方法:

WHILE 1 = 1
BEGIN
    UPDATE  TOP (100) ....
    SET     ...


    IF @@ROWCOUNT = 0
        BREAK;
END

我认为这比做类似的事情没有任何好处:

SELECT 1;
WHILE  @@ROWCOUNT > 0
BEGIN
    ...
END

而且更啰嗦,但做一个毫无意义的选择或分配让我觉得很奇怪,可能是由于一些轻微的强迫症。

【讨论】:

  • 我喜欢这些答案,而且我确实喜欢在其他永久循环中使用中断。不过,我确实注意到,在尝试 print go print 查询时,我可以删除 go 并获得相同的结果但是,在选择和打印之间进行切换似乎不会影响行数,因此这可能不准确,或者可能不是 SQL Studio 处理它的方式。
  • 您确实是正确的,使用PRINT 会将@@ROWCOUNT 设置为0。所以我所说的新批次重置它是无稽之谈。我已经删除了。
【解决方案2】:

@@Rowcount 是系统函数,输出INT NOT NULL --> default value for int is 0

您可以通过以下方式获得它:

if @@rowcount = 0
    print 1
else 
    print 0

但不要在第一行尝试select @@rowcount,它是进行简单赋值的语句,并且始终将@@ROWCOUNT 值设置为1。:)

所以解决方案是在您的while 之前添加select 0。之所以有效,是因为 select 0 中的 @@rowcount 是一排..

select 0
while (@@Rowcount <> 0)
begin
    update top (800) etc etc
end

【讨论】:

    【解决方案3】:

    @@RowCount 的值保存在变量中可以避免对初始值的任何假设以及在执行另一条语句时丢失值的任何问题。

    declare @Samples as Table ( Sample Int );
    insert into @Samples ( Sample ) values ( 1 ), ( 2 ), ( 5 );
    
    declare @RowCount as Int;
    -- If there is any work to do then initialize   @RowCount   to   1 , otherwise   0 .
    set @RowCount = case when exists ( select 42 from @Samples where Sample < 10 ) then 1 else 0 end;
    declare @NewSample as Int, @OldSample as Int;
    
    -- Loop through updating one row at a time.
    while @RowCount > 0
      begin
      update Ph
        set @OldSample = Sample, @NewSample = Sample *= 2
        from ( select top 1 Sample from @Samples where Sample < 10 order by Sample ) as Ph
      set @RowCount = @@RowCount;
      -- Do what you will without losing the count of rows updated.
      select @RowCount as 'RowsProcessed', @OldSample as 'OldSample', @NewSample as 'NewSample'
      end
    

    【讨论】:

      猜你喜欢
      • 2011-05-28
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多