Sql server Sql Server在while循环期间打印受影响的行
我有一个在sql server 2008上运行的存储过程,它在大约5000万行的表上循环,每天删除记录,大约每天删除25000条记录。我希望能够在流程通过打印语句运行到消息窗口时看到这种情况。我希望在每一天的删除工作完成时都能看到一条消息。有没有办法做这样的事?程序大致如下所示:Sql server Sql Server在while循环期间打印受影响的行,sql-server,sql-server-2008,stored-procedures,printing,Sql Server,Sql Server 2008,Stored Procedures,Printing,我有一个在sql server 2008上运行的存储过程,它在大约5000万行的表上循环,每天删除记录,大约每天删除25000条记录。我希望能够在流程通过打印语句运行到消息窗口时看到这种情况。我希望在每一天的删除工作完成时都能看到一条消息。有没有办法做这样的事?程序大致如下所示: WHILE EXISTS(<query statement>) BEGIN BEGIN TRAN DELETE FROM <table> WHERE <condition> A
WHILE EXISTS(<query statement>)
BEGIN
BEGIN TRAN
DELETE
FROM <table>
WHERE <condition>
AND <condition>
--need some sort of "rows affected" statement here
COMMIT
END
RAISERROR ('MY MESSAGE', 0, 1) WITH NOWAIT
不幸的是,PRINT语句输出是假脱机的,不能立即写入输出。解决此问题的一种方法是使用如下错误:
WHILE EXISTS(<query statement>)
BEGIN
BEGIN TRAN
DELETE
FROM <table>
WHERE <condition>
AND <condition>
--need some sort of "rows affected" statement here
COMMIT
END
RAISERROR ('MY MESSAGE', 0, 1) WITH NOWAIT
特别针对您想要的:
DECLARE @Msg VARCHAR(200)
WHILE EXISTS(<query statement>)
BEGIN
BEGIN TRAN
DELETE
FROM <table>
WHERE <condition>
AND <condition>
SELECT @Msg = CAST(@@ROWCOUNT AS VARCHAR(10)) + ' rows affected'
RAISERROR (@Msg, 0, 1) WITH NOWAIT
COMMIT
END
我还倾向于在消息中包含当前时间,以便记录时间进度。还有比select@@rowcount更复杂的吗?使用OUTPUT子句怎么样??是否可以从存储的进程写入SQL Server控制台 与触发器一样,您手头有一个已删除的伪表,其中包含要删除的行及其所有列
WHILE EXISTS(<query statement>)
BEGIN
BEGIN TRAN
DELETE FROM <table>
OUTPUT deleted.ID, deleted.TimeStamp -- or whatever
WHERE <condition>
AND <condition>
COMMIT
END
我以前也做过类似的事情,因为在后台打印时没有太多用处,但是我发现命令行实用程序osql会立即输出它们,所以我编写了存储过程,并从批处理文件调用它,这让我看到了进度。执行以下操作:
DECLARE @queryCount AS INT, @start AS INT, @stop as INT, @table as varchar(max)
SELECT @start = cnt(*) as a FROM <table>
SELECT @queryCount = cnt(*)
FROM <table>
WHERE <condition>
AND <condition>
DELETE
FROM <table>
WHERE <condition>
AND <condition>
SELECT @stop = cnt(*) as a FROM <table>
PRINT(convert(varchar(max), @queryCount) + ' rows deleted from ' + convert(varchar(max), @table))
警告:如果数据库在这一过程中会影响行,您可能会看到差异。您可以这样做来迭代每一行
declare @ii (id int) table
-- for batchchunk operations
declare @numTransactions as int = 0,
@totalRowsInserted as int = 0,
@chunksize int = 0,
@printnow varchar(1000)
--does the initial insert into the table
select * from #table
SET @numTransactions =@@rowcount
SET @printnow = 'Should Insert :'+cast(@numTransactions as varchar)+ ' rows into the table.'
exec db.printNow @printnow; -- shortened proc
BEGIN
INSERTCHUNKS:
SET ROWCOUNT @Batchsize
insert into table
(
type_id,
parent_id,
created_by_user_id,
created_at,
updated_by_user_id,
updated_at,
created_by_system_id,
updated_by_system_id,
is_deleted
)
output inserted.id into @ii(id)
select
1,--party_type_id
NULL,--parent_party_id
@user_id, --created_by_user_id
case when created_at is NULL then getdate() else created_at end ,
NULL , --updated_by_user_id
case when updated_at is NULL then getdate() else updated_at end, --
updated_at
case when created_by_system_id is null then 292 else 0 end, --created_by_system_id
updated_by_system_id,--updated_by_system_id \
0 --is_deleted
from
#table
order by id asc
OFFSET
@TotalRowsInserted ROWS
FETCH NEXT @batchsize ROWS ONLY
set @chunksize =@@rowcount
IF @chunksize > 0
BEGIN
set @totalRowsInserted = @totalRowsInserted + @chunksize
SET @printnow = 'Batch done: ' +
cast(@chunksize as varchar) + ' rows in Batch ; '
+ cast(@totalRowsInserted as varchar) + ' total inserted so far
into the table.' exec db.printnow @printnow;
waitfor delay '00:00:01'
GOTO INSERTCHUNKS
END
SET ROWCOUNT 0;
END
我不想看到每批删除的每一行,只想看到它们的总数。我不确定您是否可以使用OUTPUT子句获得该功能。您可以将输出定向到一个临时表中,然后在WHILE循环后计算该临时表中的行数。这是可行的,但我仍然不确定如何在每个批处理期间获取受delete影响的行数。对此有何想法?请确保查看SSMS中的Messages选项卡以查看RaiseError的输出。RaiseError输出只会在查询完成后出现在“结果”选项卡中。正如Chris Smith所指出的,请查看“结果”选项卡旁边的“消息”选项卡,或者将输出模式更改为文本而不是网格。很好,不复杂!SQL server倾向于缓冲打印命令,并在循环结束时将它们全部输出。您能否解释一下,当在循环语句中使用时,这将如何工作?