国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

深入講解游標類型為什么會產生數據檢索

2024-07-21 02:42:30
字體:
來源:轉載
供稿:網友
游標類型產生的數據檢索問題:

現象:

在將數據庫兼容的級別從80改到90以后, 下文中的游標循環不出數據, 單獨SELECT卻會有結果:

DECLARE MyCursor CURSOR LOCAL READ_ONLY

FOR

SELECT

Col1

FROM tbname WITH(NOLOCK)

WHERE Name LIKE 'SNET%'

AND B_Key IN(

SELECT TOP(100)

KeyID

FROM tbmaster WITH(NOLOCK)

WHERE Date >= '01/01/2007'

AND Date < '02/01/2007')

OPEN MyCursor

FETCH NEXT FROM MYCURSOR

WHILE (@@FETCH_STATUS=0)

BEGIN

FETCH NEXT FROM MYCURSOR

END

CLOSE MyCursor

DEALLOCATE MyCursor

原因:

游標類型的問題。

參照以上的定義, 游標類型是: DYNAMIC

在定義此類游標的情況下, S鎖是必須下的, NOLOCK提示并不會起作用,此現象通過查詢游標OPEN時的sp_lock信息就可以觀察得到。它產生了IS和S鎖。

而NOLOCK 提示是否起作用, 會影響的執行的結果(執行計劃一樣, 但在取數據的時候, 卻會有所差異)

對于下面這句, 有NOLOCK 和無NOLOCK 時, 它取的數據是不一樣的, 因為它只取了TOP 100, 而且沒有ORDER BY 來保證取數的順序, 所以取數據順序的細致差異, 就導致了最終結果的不同. 而最終結果的不同, 導致了整個游標取出來的數據不同。

SELECT TOP(100)

KeyID

FROM tbmaster WITH(NOLOCK)

WHERE Date >= '01/01/2007'

AND Date < '02/01/2007')

在游標定義SELECT 語句中, 當NOLOCK 有效時, 是可以取到數據的, 但NOLOCK 無效(DYNAMIC 游標導致)時, 查詢結果是無數據的

所以最終看到的結果是: 游標循環不出來數據, 但只做查詢卻有數據。

如果把游標定義中的查詢語句的NOLOCK 去掉做查詢, 也會沒有數據(與DYNAMIC 游標結果一致)

故這個問題嚴格來說不應該是兼容級別的問題, 在80 級別下, 還是有可能發生, 只是機率更小, 或者是內部執行原理不太一樣, 導致沒有這種情況出來而已

由于沒有ORDER BY來保證順序, 而有無NOLOCK的數據可能不會一樣, 所以80與90下都可能出現問題, 只是90會顯得比較突出, 或者僅僅時正好被發現了。

解決方法如下:

首先,需要把游標定義改成下面的,這樣不會導致NOLOCK 失效, 而且速度比原來的定義方式快得多. 如果游標一定要與原始表的數據變化關聯起來, 建議用KEYSET, 或者是去掉NOLOCK 提示(因為沒有意義), 假如對取的數據有要求, 我們還應當考慮加ORDER BY來保證取數順序:

DECLARE MyCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY STATIC

FOR


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广河县| 三明市| 洛宁县| 苗栗市| 仲巴县| 秭归县| 凉山| 来宾市| 海口市| 古丈县| 苏尼特左旗| 满城县| 马尔康县| 台州市| 洪江市| 安塞县| 青河县| 垣曲县| 舟曲县| 桂林市| 衡阳县| 清水河县| 慈溪市| 方山县| 永定县| 历史| 东至县| 博湖县| 凤台县| 醴陵市| 肥乡县| 淮安市| 曲周县| 黎川县| 新平| 柯坪县| 临朐县| 丹阳市| 化州市| 天全县| 商都县|