SQL Server 中游標的使用sql
1.遊標是行讀取,佔用資源比sql多
2.遊標的使用情景:
->現存的系統中使用的是遊標,查詢必須經過遊標來實現
->用盡了while、子查詢臨時表、表變量、自定義函數以及其餘方式仍然沒法實現的時候,使用遊標
3.T-SQL 中游標的生命週期由5部分組成
->定義遊標:遊標的定義遵循T-Sql的定義方法,賦值有兩種方法,定義時賦值,和先定義後賦值,定義遊標像定義其餘局部變量同樣前面要加@,注意若是是全局的遊標,只支持定義時直接賦值,而且不能在遊標前面加@
--定義時直接賦值
Declare test_Cursor Cursor For
select * from dbo.tb1
--先定義後賦值
Declare @test_Cursor2 Cursor
set @test_Cursor2=Cursor For
select * from dbo.tb2
Local和Global
Local意味着遊標的生命週期只在批處理或函數或存儲過程當中可見,而Global意味着遊標對於特定的鏈接做爲上下文,全局有效
--定義後直接賦值(全局)
Declare test_Cursor Cursor GLOBAL For
select * from dbo.tb1
--(局部)
Declare test_Cursor2 Cursor LOCAL For
select * from dbo.tb2
--用GO結束上面的做用域
GO
Open test_Cursor
Open test_Cursor2
報錯:test_Cursor2不存在
注意:若是不指定遊標做用域,默認爲GLOBAL
Forward_Only和Scroll 二選一
Forward_Only意味着遊標只能從數據集開始向着數據集結束的方向讀取,惟一選項Fetch Next,而Scroll支持遊標在定義數據集上向着任何方向或者任何位置移動
--不加參數默認爲Forward_only
Declare test_Cursor Cursor For
select * from dbo.tb1
--加Forward_Only
Declare test_Cursor2 Cursor Forward_Only For
select * from dbo.tb1
--加Scroll
Declare test_Cursor3 Cursor Scroll For
select * from dbo.tb1
Open test_Cursor
Open test_Cursor2
Open test_Cursor3
Fetch Last from test_Cursor
Fetch Last from test_Cursor2
Fetch Last from test_Cursor3--讀取最後一行
報錯:只進遊標test_Cursor不能與last一塊兒使用,只進遊標test_Cursor2不能與last一塊兒使用
Static Keyset Dynamic 和 Fast_Forward四選一
這四個關鍵字是遊標所在的數據集所反應的表內數據和遊表讀取出數據的關係。
Static:意味着,當遊標被創建時候,將會建立For後面的select 語句所包含數據集的副本存入tempdb數據庫中,任何對於底層表內數據的更改不會影響到遊標的內容
Dynamic:是和Static徹底相反的選項,當底層數據庫更改時,遊標的內容也隨之待到放映,在下一次fetch中,數據內容會隨之改變
Keyset:能夠理解爲介於Static和Dynamic的折中方案。蔣友柏所在結果集的惟一能肯定每一行的主鍵存入tempdb,當結果中任何行改變或者刪除時,@@FETCH_STATUS爲-2,KEYSET沒法探測新加入的數據
FAST_FORWAED能夠理解成FORWARD_ONLY的優化版本,FORWARD_ONLY執行的是經計劃,而FAST_FORWARD是根據狀況進行選擇採用動態計劃仍是靜態計劃,大多數狀況下FAST_FORWARD要比FORWARD_ONLY性能略好
READ_ONLY SCROLL_LOCKS OPTIMISTIC三選一
READ_ONLY:意味着聲明的遊標只能讀取數據,遊標不能作任何更新操做
SCROLL_LOCKS:是另外一種極端,將讀入遊標的全部數據進行鎖定,防止其餘程序進行更改,以確保更行的絕對成功
OPTIMISTIC:是相對比較好的一個選擇,OPTIMISTIC不鎖定任何數據,當須要在遊標中更新數據時,若是底層數據更新,測遊標內數據更新不成功,若是底層表數據爲更新,則遊標南日表數據能夠更新
->打開遊標:Open test_Cursor 注意,當全局遊標和局部遊標變量重名時,默認會打開局部變量遊標
->使用遊標:遊標分爲兩部分,一部分是操做遊標在數據集內的指向,另外一部分是將遊標所直向的行的部分或所有內容進行操做
只支持6中移動選項,到第一行(FIRST),最後一行(LAST),下一行(NEXT),上一行(PRIOR),直接跳到某一行(ABSOLUTE(n)),相對於目前跳到幾行(RELATIVE(n))
--必須指定SCROLL不然只支持next只進選項
DECLARE test_Cursor SCROLL FOR
select * from dbo.tb1
OPEN test_Cursor
DECLARE @c nvarchar(10)
--取下一行
Fetch next from test_Cursor into @c
print @c
--取最後一行
Fetch Last From test_Cursor into @c
print @c
--取第一行
Fetch first from test_Cursor into @c
print @c
--取上一行
fetch prior from test_Cursor into @c
print @c
--取第三行
fetch absolute 3 from test_Cursor into @c
print @c
--取相對目前來講上一行(-2相對於目前來講向上移動2行,2對目前來講向下移動2行)
fetch relative -1 from test_Cursor into @c
print @c
對於爲指定SCROLL的,只能用NEXT選項
遊標常常回和全局變量@@FETCH_STATUS 與WHITLE循環來共同使用,歷來遍歷遊標所在的數據集
Declare test_Cursor cursor scroll for
select id,name from dbo.tb1
Open test_Cursor
Declare @id int
Declare @name nvarchar(10)
while @@FETCH_STATUS=0
begin
print @id
print @name
Fetch next from test_Cursor into @id,@name
end
Close test_Cursor
Deallocate test_Cursor
->關閉遊標: Close test_Cursor
->釋放遊標: Deallocate test_Cursor
註釋1:
->遊標的定義的複雜程度是和參數有關,而遊標的參數設置是對遊標的原理了解程度。
->遊標的原理:遊標是定義在特定數據集上的指針,咱們控制這個指針遍歷數據集,或者僅僅是指向特定的行,因此遊標是定義在以select開始的數據集上的。
註釋2:
若是能不用遊標,儘可能不要使用遊標
用完用完以後必定要關閉和釋放
儘可能不要在大量數據上定義遊標
儘可能不要使用遊標上更新數據
儘可能不要使用insensitive, static和keyset這些參數定義遊標
若是能夠,儘可能使用FAST_FORWARD關鍵字定義遊標
若是隻對數據進行讀取,當讀取時只用到FETCH NEXT選項,則最好使用FORWARD_ONLY參數數據庫