2008-11-20 39 views
183

我在SQL Server 2005中有一個非常長時間運行的存儲過程,我正在嘗試調試,並且使用'print'命令來執行它。問題是,我只是在我的sproc的末尾從SQL Server獲取消息 - 我希望能夠刷新消息緩衝區,並在sproc的運行時期間立即看到這些消息,而不是在結束。如何在TSQL中刷新PRINT緩衝區?

回答

260

使用RAISERROR功能:

RAISERROR('This message will show up right away...',0,1) WITH NOWAIT 

你不應該完全取代RAISERROR所有打印件。如果你在某個地方有一個循環或者大光標,那麼每次迭代只做一次或者兩次,或者甚至每隔幾次迭代。

另外:我第一次瞭解RAISERROR在這個環節,這是我現在考慮的SQL Server中的錯誤處理的最終來源,確實值得一讀:
http://www.sommarskog.se/error-handling-I.html

+33

請注意,SQL中的TRY/CATCH只會捕獲嚴重性> 10的錯誤,因此以這種方式使用RAISERROR不會跳入您的CATCH語句。這很好,因爲這意味着你仍然可以像TRY/CATCH一樣使用RAISERROR。 ref:http://msdn.microsoft.com/en-us/library/ms175976.aspx – Rory 2011-04-12 22:24:55

+8

請注意,這不起作用的第500條消息;一旦你打印更多,它突然開始緩衝! – GendoIkari 2015-09-10 20:51:02

+0

@GendoIkari我有同樣的問題。你解決了嗎? – 2015-10-13 10:08:42

15

是... RAISERROR的第一個參數函數需要一個NVARCHAR變量。所以嘗試以下;

-- Replace PRINT function 
DECLARE @strMsg NVARCHAR(100) 
SELECT @strMsg = 'Here''s your message...' 
RAISERROR (@strMsg, 0, 1) WITH NOWAIT 

OR

RAISERROR (n'Here''s your message...', 0, 1) WITH NOWAIT 
3

只爲參考,如果您在腳本(批處理),而不是在存儲過程工作,沖洗輸出由GO命令,例如觸發

print 'test' 
print 'test' 
go 

一般情況下,我的結論是以下幾點:MSSQL腳本執行的輸出,在短信界面或sqlcmd.exe執行,將刷新到文件,stdoutput,GUI窗口上第一GO語句或直到的結束腳本。

存儲過程內部的刷新功能不同,因爲你不能放置GO。

參考:tsql Go statement

9

另一種更好的選擇是不依賴於PRINT或RAISERROR,只是加載您的「打印」語句到在tempdb中一個## TEMP表或數據庫中的一個永久表,這將給你的知名度通過另一個窗口的SELECT語句立即生成數據。這對我來說最合適。使用永久性表格也可以作爲過去發生的事件的記錄。打印語句對於錯誤非常方便,但是使用日誌表還可以根據特定執行的最後一個記錄值(假設您跟蹤日誌表中的總體執行開始時間)來確定確切的故障點。

3

建立在@JoelCoehoorn的答案上,我的方法是保留所有的PRINT語句,並簡單地按照RAISERROR語句來引起刷新。

例如:

PRINT 'MyVariableName: ' + @MyVariableName 
RAISERROR(N'', 0, 1) WITH NOWAIT 

這種方法的優點是打印語句可以連接字符串,而RAISERROR不能。 (所以無論哪種方式,您都有相同數量的代碼行,因爲您必須聲明並設置要在RAISERROR中使用的變量)。

如果像我一樣使用AutoHotKey或SSMSBoost或等效工具,則可以輕鬆設置快捷方式(如「] flush」來爲您輸入RAISERROR行。如果每次都是相同的代碼行,即不需要定製以保存特定的文本或變量,這樣可以節省您的時間。