我正在看this query ,我对一些事情感到困惑。
-- T-SQL large update table
USE tempdb;
SELECT * INTO SOD
FROM AdventureWorks2008.Sales.SalesOrderDetail
GO
--(121317 row(s) affected)
-- SQL update in batches of 10,000
WHILE (2 > 1)
BEGIN
BEGIN TRANSACTION
UPDATE TOP ( 10000 ) SOD
SET UnitPriceDiscount = 0.08,
ModifiedDate = CONVERT(DATETIME,CONVERT(CHAR(10),getdate(),112))
WHERE ModifiedDate < CONVERT(DATETIME,CONVERT(CHAR(10),getdate(),112))
IF @@ROWCOUNT = 0
BEGIN
COMMIT TRANSACTION
BREAK
END
COMMIT TRANSACTION
-- 1 second delay
WAITFOR DELAY '00:00:01'
END -- WHILE
GO
/* Messages
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(10000 row(s) affected)
(1317 row(s) affected)
(0 row(s) affected)
*/
-- Cleanup
DROP TABLE SOD
GO
------------
SELECT * INTO SOD
如果真的需要这个吗?我可以只使用while部分及以下部分吗?IF @@ROWCOUNT = 0
如何变为零?它会自我增量还是什么?修改
这就是我现在所拥有的,但我仍然认为有无穷无尽的循环或其他东西
BEGIN TRAN
declare
@rows_updated int ,
@rowCount int,
@batch_size int
set @rows_updated = -1
set @batch_size = 10000
set @rowCount = 0;
Declare @xx VARCHAR(20) DECLARE @length INT
SET @length = 17 SET @xx = 'XXXXXXXXXXXXXXXX'
while ( @rows_updated != 0 )
begin
update top(@batch_size) myTbl
SET myNumber = SUBSTRING(@xx, 0, @length - len(RIGHT(myNumber, 4))) + RIGHT(myNumber, 4)
WHERE myDate <'2011-Jan-02'
set @rows_updated = @@rowcount
set @rowCount += 10000
print @rowCount
end
ROLLBACK
我做了一次计数
select count(*) from myTbl
where myDate < '2011-Jan-02'
这会带回1,448,982
我得到的最后一次打印是31,110,000
修改2
我添加了这个,现在它停止但它仍然不是100%它应该在
while (Select Count(*) From myTbl Where myDate <'2011-Jan-02' ) >= @rowCount
编辑3
我认为编辑2只是一遍又一遍地做同样的10,000行。
答案 0 :(得分:2)
SOD
是由SELECT ... INTO
语句创建的新表,请参阅here @@ROWCOUNT
语句不再更新任何记录时,或者换句话说,UPDATE
表中的所有记录都已更新时,SOD
变为0。编辑修正了第一个答案
答案 1 :(得分:1)
提供的脚本执行以下操作:
创建/加载永久表SOD
while(true)
首先,正常安装SQL Server时不需要begin transaction
和commit transaction
,除非您通过执行IMPLICIT_TRANSACTIONS
明确更改了SET IMPLICIT_TRANSACTIONS ON
设置,其中如果BEGIN TRANSACTION
语句不可用。原因是默认情况下,SQL Server以自动提交模式运行,因此每个语句都会触发, sotto voce ,成功时commit
或失败时rollback
。< / p>
此外,逻辑有点笨重。我会写这样的循环:
declare
@rows_updated int ,
@batch_size int
set @rows_updated = -1
set @batch_size = 10000
while ( @rows_updated != 0 )
begin
update top @batch_size SOD
set UnitPriceDiscount = 0.08 ,
ModifiedDate = convert(datetime,convert(char(10),getdate(),112))
where ModifiedDate < convert(datetime,convert(char(10),getdate(),112))
set @rows_updated = @@rowcount
end
这可能会让事情变得更加透明。
答案 2 :(得分:0)
它不是临时表,SELECT ... INTO SOD FROM ...
正在创建SalesOrderDetail
表的精确副本(数据和模式)。表SOD
在此语句之前不能存在,否则SQL Server将抛出错误。与临时表不同,SOD
会一直持续到DROP TABLE
运行。临时表仅在创建进程ID的持续时间内存在(或者,因为您在tempdb
中创建表,它将在下次SQL Server重新启动时消失。)
@@rowcount
将为零。换句话说,当没有更新行时,@@rowcount
将为零并突破无限循环。
答案 3 :(得分:0)
它正在AdventureWorks2008.Sales.SalesOrderDetail
中复制tempdb
。然后,UPDATE
SOD
表10000
一次记录@@ROWCOUNT
。这是在表很大时完成的,因为较小的事务更快完成,从而减少了对表的争用。
SET ROWCOUNT OFF
,否则 SOD
在任何DML语句之后在内部更新。所以最终,SOD
将没有任何合格记录,也不会更新任何记录,这将结束循环。
由于{{1}}最终被抛弃,整件事似乎毫无意义。所以,除非这段代码更多,否则我无法理解为什么要制作,更新,然后删除副本。