2012-10-24 159 views
3

做了一些閱讀之後,很明顯多個程序可以修改全局變量@@Fetch_Status。我們有一個存儲過程,每小時調用一次其他存儲過程(類似於一個表驅動的觸發器,這樣客戶端就可以控制,但不需要觸摸,只有一個觸發器)。所以這個調用這些子程序的父程序使用了一個遊標。一些子程序也可以使用遊標。我應該避免@@ Fetch_Status?

我知道每個Fetch Next調用幾乎緊跟一個@@Fetch_Status電話,但事情並行發生的我不知道,如果調用@@Fetch_Status是線程安全的,特別是考慮到備註部分here。所以,我認爲這將是一個好主意,以取代我所有的While @@Fetch_Status = 0)調用能夠像

WHILE ((SELECT fetch_status 
FROM sys.dm_exec_cursors(0) 
where name = 'server_cursor')=0) BEGIN 

這在我的電腦上偉大的工作,但是當我把它轉移到客戶端機器我才知道,我沒有選擇sys.dm_exec_cursors(0)表中的權限。我收到錯誤The user does not have permission to perform this action.

或者,如果我嘗試select * from sys.syscursors我得到的錯誤The SELECT permission was denied on the object 'syscursors', database 'mssqlsystemresource', schema 'sys'.

是否有另一種方式做到這一點,以確保多個同時光標在彼此不踩?或者我在這裏工作太辛苦了?

+1

'返回當前由連接打開的任何遊標所發出的最後一個遊標FETCH語句的狀態。'因此,如果在調用'FETCH'和檢查之間使用遊標的'EXEC'語句應該只有一個問題'@@ Fetch_Status'。 –

+0

當然,沒有一個過程是這樣寫的,但procA和procB都使用遊標,procA調用下一行,但在它可以檢查獲取狀態procB之前,並行讀取最後一行,從而設置全局'@ @ Fetch_Status'爲-1。然後,當procA去檢查'@@ Fetch_Status'它認爲它的行都被提取,但他們不是。或者SQL比這更聰明? – Brad

+1

來自單個連接的程序不會並行運行。可以並行運行的唯一事情就是針對單個查詢的並行執行計劃。 –

回答

0

解決方法是在您的FETCH NEXT聲明之後檢查@@FETCH_STATUS。特別是,確保沒有可能改變狀態的中間呼叫。如有必要,您可以將該值保存到聲明的局部變量中。你提到檢查狀態「幾乎立即」。如果你不確定,你最好檢查你的代碼。

否則,@@FETCH_STATUS應該是可靠的。