2010-11-22 58 views
7

在T-SQL遊標可通過兩種方式進行聲明(即我所知道的):優勢(聲明@cn光標)

  1. declare CursorName cursor for ...
  2. declare @CursorName cursor

我正在運行一些測試,我注意到創建一個遊標變量不會在sp_cursor_list的結果中添加一個條目。

從性能,資源利用等角度來看,使用第二種方法是否有優勢/劣勢?

PS:我知道潛在的遊標性能問題。我不是要求比較遊標和基於集合的比較。或光標與while與臨時/表變量。

+3

如果性能是一個考慮因素,你可能不應該使用遊標:) – JNK 2010-11-22 18:14:37

+0

如果您發佈代碼或XML,**請**在文本編輯器中突出顯示這些行,然後單擊編輯器工具欄上的「代碼」按鈕(101 010),以良好地格式化和語法突出顯示它! – 2010-11-22 18:21:33

回答

4

從我讀的遊標變量的目的是爲了能夠使用它作爲存儲過程中的輸出變量,從而使您能夠將光標中的數據發送到另一個控制過程。我沒有試過這個,所以我不知道它會如何工作,但這是我從閱讀聯機叢書中得到的。如果有任何可衡量的性能差異,並且肯定不是首先不使用光標所能獲得的改進,我會感到驚訝。如果你不打算將它用作輸出變量,我建議繼續使用更常見的遊標定義可能會使代碼更容易維護。

也就是說,實際上需要遊標的情況非常少。

0

我會盡量避免詛咒者(至少如果你考慮性能的話)。嘗試爲您的問題創建一套基於解決方案。他們通常會比基於光標的解決方案處理速度快得多。

4

使用我剛發現的DECLARE @local_variable CURSOR語法還有另一個好處。

當一個存儲過程調用另一個存儲過程並且兩個過程同時打開遊標時,就會出現這種優勢。如果DECLARE cursor_name CURSOR被用來定義遊標和程序都使用相同的CURSOR_NAME,那麼你得到

消息16915:遊標名稱爲「CURSOR_NAME」已經存在。

在另一方面,如果DECLARE @local_variable CURSOR用於定義父和子存儲過程的遊標,然後@local_variable是本地的每個過程並沒有衝突。對於那些誰沒有以前使用這種方法,這裏有一個例子,使用@C作爲局部變量:

DECLARE @C AS CURSOR; 

SET @C = CURSOR FOR SELECT ...; 

OPEN @C; 

FETCH NEXT FROM @C INTO ...; 

...