解讀SQL Server游標使用實例_Mssql數據庫教程
推薦:在SQL Server中通過.NET遠程的執行SQL文件在項目開發過程中,操作數據庫的過程中經常會遇到對表結構、存儲過程等進行修改,這時一般的操作都是通過直接在SQL Server中的企業管理器進行操作,或者查詢分析器里來執行相關的語句
問題
在我的T-SQL代碼中,我經常使用基于集合的運算。我被告知這些運算的類型正是SQL Server設計所處理的,并且它應該比串行處理要快些。我知道游標的存在但是我不確定如何使用它們。您能提供一些游標的例子嗎?您能否給一些關于何時使用游標的指導?我假定微軟由于某種原因創建了它們,所以它們必須有以高效方式使用的地方。
專家解答
在某些圈子中,游標從未被使用過,在其他圈子中,它們是一種最后手段,而在其它組中它們經常被使用。在每個組中,它們由于不同原因而使用游標。無論你對游標使用原因有什么樣的立場,可能它們在一個特定環境中具有用武之地而在另一個環境中卻沒有用處。所以它歸結于你對這個技術的理解,然后歸結于隨及而來對問題的理解導致做出一個決定,這個決定就是基于游標的過程是否恰當。讓我們先來做以下幾件事情:
l 看一個游標實例
l 分解游標的組成部分
l 分析使用游標的優缺點
游標實例
以下是一個游標實例,講述了備份在串行狀態下如何執行。
| 以下為引用的內容: DECLARE@nameVARCHAR(50)--databasename DECLARE@pathVARCHAR(256)--pathforbackupfiles DECLARE@fileNameVARCHAR(256)--filenameforbackup DECLARE@fileDateVARCHAR(20)--usedforfilename SET@path='C:Backup' SELECT@fileDate=CONVERT(VARCHAR(20),GETDATE(),112) DECLAREdb_cursorCURSORFOR SELECTname FROMmaster.dbo.sysdatabases WHEREnameNOTIN('master','model','msdb','tempdb') OPENdb_cursor FETCHNEXTFROMdb_cursorINTO@name WHILE@@FETCH_STATUS=0 BEGIN SET@fileName=@path @name '_' @fileDate '.BAK' BACKUPDATABASE@nameTODISK=@fileName FETCHNEXTFROMdb_cursorINTO@name END CLOSEdb_cursor DEALLOCATEdb_cursor |
游標組成
根據以上的實例,游標包括這些組成部分:
l DECLARE語句 – 聲明在代碼塊中使用的變量
l SETSELECT語句 – 把這些變量初始化為某個具體的值
l DECLARE CURSOR語句 – 在游標中填充將要求取的值。
注意 – DECLARE CURSOR FOR語句和SELECT語句中具有相同數量的變量。變量數目可能是一個或者很多個并且有相關聯的列。
l OPEN語句 – 打開游標,開始進行數據處理
l FETCH NEXT語句 – 從游標中把具體的值分配給變量
注意: 這個邏輯用于WHILE語句之前的初始對象,接著作為WHILE語句的一部分在這個過程的每個循環中再次執行。
l WHILE語句 – 作為開始的條件,繼續處理數據
l BEGIN...END語句 – 代碼塊的開始和結束
注意:按照不同的數據處理,可以使用不同的BEGIN...END語句
l 數據處理 – 在這個例子中,邏輯是用來把一個數據庫備份到具體的路徑和文件名,但是這可以只與任何DML或者管理邏輯有關。
l CLOSE語句 – 釋放當前的數據和相關聯的鎖,但是允許游標重新打開。
l DEALLOCATE語句 – 破壞游標
游標分析
以下分析旨在更深入了解基于游標的邏輯是否有利:
l 聯機事務處理(OLTP)- 在大多數的聯機事務處理環境中,基于集合的邏輯適合簡短的事務。我們的團隊已經遇到第三方應用,這個應用在它所有的過程中使用游標,這將導致一些問題,但這是一個很罕見的現象。通常情況下,基于集合的邏輯足夠靈活而且游標很少被用到。
l 報表 – 基于報表的設計和潛在設計,通常情況下游標是不需要的。盡管如此,我們的團隊遇到報表要求,而參照完整性沒有存在于潛在的數據庫中,同時需要使用游標來正確計算報表值。當需要下游過程的合計數據時,我們面臨相同的狀況,一個基于游標的方法可以用一種可接受的方式快速形成和執行來滿足要求。
l 串行化過程 – 如果你需要以串行化方式完成一個過程,那么游標是一個可行的選項。
l 管理員任務 – 很多管理員任務需要在串行狀態下執行,這與基于游標的邏輯很相符,但是基于其他系統的對象存在來滿足這種需要。在某些情況下,游標用來完成這一進程。
l 大型數據集 – 在大型數據集的情況下,你可能會遇到以下任何一種情況:
基于游標的邏輯可能沒有足夠大的規模滿足需求。
在服務器上具有大型數據集的運算而內存又很小,數據可能會被分頁或獨占SQL Server,這將是很費時間的,可能會導致爭奪和內存的問題。
有些固有的工具把數據存儲到一個隱藏的文件中,所以在內存中處理數據可能會也可能不會是實際的情況。
如果數據能夠在一個中間數據庫中處理,那么對生產環境的影響只有在最后數據被處理時,所以服務器上所有的資源可用于ETL過程,然后引入最后的數據。
SSIS支持批處理數據,這將解決把大量數據分解成更多可管理的大小和比用按行方法執行效果更好的總體需求。
根據游標或者SSIS邏輯如何編碼,它可能基于檢查點或者在游標的每一行做標記來在失敗時重新啟動。盡管如此,用可能并非事實的基于集合的方法直到獲得數據的整個集合是完整的。同樣地,解決行的問題會更加困難。
游標的替代
下面列出了可以替代能夠滿足相同需求的基于游標的邏輯:
l 基于集合的邏輯
l SSIS或者數據轉換服務
l WHILE循環
l COALSCE
l sp_MSforeachdb
l sp_MSforeachtable
l CASE表達
l 用GO命令重復一批數據
分享:解析Microsoft SQL Server數據庫日志截斷參考 壓縮日志及數據庫文件大小 /*--注意事項 請按步驟進行,未進行前面的步驟,請不要做后面的步驟,否則可能損壞你的數據庫. 一般情況下不建議做第4,6兩步。 第4步不安全,
- sql 語句練習與答案
- 深入C++ string.find()函數的用法總結
- SQL Server中刪除重復數據的幾個方法
- sql刪除重復數據的詳細方法
- SQL SERVER 2000安裝教程圖文詳解
- 使用sql server management studio 2008 無法查看數據庫,提示 無法為該請求檢索數據 錯誤916解決方法
- SQLServer日志清空語句(sql2000,sql2005,sql2008)
- Sql Server 2008完全卸載方法(其他版本類似)
- sql server 2008 不允許保存更改,您所做的更改要求刪除并重新創建以下表
- SQL Server 2008 清空刪除日志文件(瞬間日志變幾M)
- Win7系統安裝MySQL5.5.21圖解教程
- 將DataTable作為存儲過程參數的用法實例詳解
- 相關鏈接:
- 教程說明:
Mssql數據庫教程-解讀SQL Server游標使用實例
。