当 SQL 作业开始时,@@ROWCOUNT 的值是多少?
When a SQL job starts, what is the value of @@ROWCOUNT?
我一直在寻找这个问题的答案,但我相信它也可能对其他人有用。
我在 SQL 服务器管理工作室与 TSQL 一起工作。由于我们的系统处理信息的方式,希望以较小的批量进行更新。我们使用的一个技巧是将更新包装在一个 while 循环中:
while (@@Rowcount <> 0)
begin
update top (800) etc etc
end
我创建了一个作业来定期执行此更新,虽然它在查询中有效 window,但它似乎在作业中不起作用。作业开始时是否填充行计数值?
@@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
@@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
而且比较啰嗦,但是做一个毫无意义的 select 或作业对我来说感觉很奇怪,也许是因为一些轻微的强迫症。
将 @@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
我一直在寻找这个问题的答案,但我相信它也可能对其他人有用。
我在 SQL 服务器管理工作室与 TSQL 一起工作。由于我们的系统处理信息的方式,希望以较小的批量进行更新。我们使用的一个技巧是将更新包装在一个 while 循环中:
while (@@Rowcount <> 0)
begin
update top (800) etc etc
end
我创建了一个作业来定期执行此更新,虽然它在查询中有效 window,但它似乎在作业中不起作用。作业开始时是否填充行计数值?
@@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
@@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
而且比较啰嗦,但是做一个毫无意义的 select 或作业对我来说感觉很奇怪,也许是因为一些轻微的强迫症。
将 @@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