使用打印跟踪时间密集型存储过程

Dae*_*hos 4 sql-server-2005 sql-server cursors

我不是数据库管理员,我的 SQL-foo 也不是很好(还),但是有一些任务需要在 MSSQL 中完成,其中一个是一个相当耗时的过程,我从 a CURSORand 中获取WHILE @@FETCH_STATUS = 0,我有多个SELECTs 和 an UPDATEon巨大的桌子。(该程序有效,我已与同事核对过)

现在在脚本或程序中,我将有一个简单的打印 @current_cursor或在每个打印一个计数器WHILE只是为了获得一些反馈。

我怎么能在 MSSQL 中做这样的事情?(使用 Microsoft SQL Server Enterprise Edition v9.00.3042.00,即 SQL Server 2005 Service Pack 2)

我可以做一个print @current_cursor,还是在我的情况下不可行?

编辑

我已经RAISEERROR用以下语句测试了:

DECLARE @cur_id int; 
SET @cur_id = 0;

DECLARE Cur CURSOR FOR
    SELECT ID FROM TableA
    WHERE ID > 100  ORDER BY ID DESC

OPEN Cur
FETCH NEXT FROM Cur INTO @cur_id;

WHILE @@FETCH_STATUS = 0
BEGIN
    RAISERROR(@cur_id, 0, 0) WITH NOWAIT
    FETCH NEXT FROM Cur INTO @cur_id;
END
Run Code Online (Sandbox Code Playgroud)

但这导致了一段时间没有输出的等待,然后是无尽的墙(我假设每个都有一个RAISERROR):

Msg 18054, Level 16, State 1, Line 17
Error 983700, severity 0, state 0 was raised, but no message with that error number was found in sys.messages. If error is larger than 50000, make sure the user-defined message is added using sp_addmessage.
Run Code Online (Sandbox Code Playgroud)

JNK*_*JNK 10

在 SQL Server 中(我认为这应该适用于您说您正在使用的旧版本),通常的方法是使用RAISERROR. PRINT在过程完成之前不会显示任何输出,这不是很有用。我在批处理脚本中经常使用这种技术来进行更新和删除,我想保持批处理大小较小。

在下面的例子中,我设置了一个@Batchsize变量,我的循环一次只处理那么多行,然后我用一个RAISERROR. 使用严重性 0 很重要,这意味着不会将其视为错误,只是作为信息性消息。

DECLARE @MsgStr varchar(200) = 'Inserted ' + CAST(@BatchSize AS varchar(10)) + ' rows...'

RAISERROR(@MsgStr, 0, 0) WITH NOWAIT
Run Code Online (Sandbox Code Playgroud)

  • JNK 和 @DaedalusMythos :我 99.99% 肯定有关“PRINT”直到过程结束才显示的声明是不正确的。它确实比“RAISERROR() WITH NOWAIT”更受阻,因为没有“WITH NOWAIT”选项,但它不会专门等待进程完成。但是,是的,带有 NOWAIT 的 RAISERROR 更好。既然您正在使用 RAISERROR,为什么还要麻烦地声明一个变量并进行强制转换呢?为什么不直接使用:`RAISERROR('Inserted %d rows; ID = %d ...', 0, 0, @BatchSize, @cur_id)`? (2认同)

Aar*_*and 5

您还可以这样做:

RAISERROR('%d', 0, 0, @cur_id) WITH NOWAIT;
Run Code Online (Sandbox Code Playgroud)

但是,根据您拥有的数量,您仍然可能会超出 Management Studio 提供的缓冲区,并且最终仍然会出现输出无法立即打印的情况。