我有一个在sql server 2008上运行的存储过程,循环遍历大约5000万行的表,一次删除一天的记录(每天大约25,000条记录)。我希望能够在流程通过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
答案 0 :(得分:23)
不幸的是,PRINT语句输出被假脱机并且不会立即写入输出。解决这个问题的方法是像这样使用RAISERROR:
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
我也倾向于在消息中包含当前时间,以便我可以记录进度与时间的关系。
答案 1 :(得分:2)
比选择@@ rowcount更复杂吗?
答案 2 :(得分:0)
如何使用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
答案 3 :(得分:0)
我曾经做过与此类似的事情,因为假冒的打印件并没有多大用处,但我发现命令行实用程序osql
会立即输出它们,所以我编写了存储过程并调用它而是从批处理文件中,让我看到进度。
答案 4 :(得分:0)
执行以下操作:
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))
如果要验证,可以输入以下代码。
PRINT('Rows at start: ' + convert(varchar(max), @start))
PRINT('Rows at end: ' + convert(varchar(max), @stop))
PRINT('Row difference: ' + convert(varchar(max), @start - @stop))
警告:如果数据库在进行此操作时可能会影响行,则可能会出现差异。
答案 5 :(得分:0)
你可以做这样的事情来迭代每一行
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