Transact-SQL中游標名的作用域
2024-07-21 02:06:41
供稿:網友
microsoft sql server 2000支持關鍵字global和local用于declare cursor 語句中游標名作用域的定義。global指定游標名在一個連接中是全局的。local指定游標名在存儲過程,觸發器,包含declare cursor的批處理語句中是局部的。
microsoft sql server 7.0版本以前,在一個連接中,游標名都是全局的。你必須先執行一個用于創建游標的存儲過程,然后再執行另外一個從該游標中讀取記錄的存儲過程。如:
use pubs
go
create procedure opencrsr as
declare samplecrsr cursor for
select au_lname
from authors
where au_lname like 's%'
open samplecrsr
go
create procedure readcrsr as
fetch next from samplecrsr
while (@@fetch_status <> -1)
begin
fetch next from samplecrsr
end
go
exec opencrsr /* 聲明并打開游標samplecrsr. */
go
exec readcrsr /* 從游標samplecrsr中讀取記錄. */
go
close samplecrsr
go
deallocate samplecrsr
go
局部游標在存儲過程和觸發器中對游標起著重要的保護作用。全局游標能在定義它們的存儲過程或觸發器外被訪問。因此,它們可能在不經意的時候,在存儲過程和觸發器外被改變。局部游標顯得更安全,因為它們不會在存儲過程和觸發器外被改變,除非特地的通過輸出游標參數被傳遞給調用者。
因為全局游標可以在存儲過程和觸發器以外被引用,所以它們可能對其他語句有不可預期的影響。例如:一個存儲過程創建一個全局游標xyz,過程運行結束后游標xyz仍然處于打開狀態,如果程序其他部分又想聲明一個全局游標并命名為xyz,這時,就會發生一個重復定義的錯誤。
全局和局部游標具有不同的命名空間,所以,在同一時間可以出現兩個具有同樣名字的全局和局部游標。transact-sql語法支持游標參數,同樣也支持使用global標識游標的作用域。如果一個游標名同時表示全局游標和局部游標,在沒有指定為global時,此游標名將引用局部游標。
數據庫選項default to local cursor控制由未指定global和local選項的declare cursor語句創建的游標的默認作用域。如果default to local cursor 選項為真,則為局部游標,反之為全局。sql server 2000中,default to local cursors 選項默認為false,用于保持與先前版本一致。
聲明并且打開局部游標的存儲過程,可以將這些游標傳出給調用它的存儲過程,觸發器和批處理語句。這可以通過一個定義為輸出參數的cursor varying 數據類型實現。當存儲過程執行結束時,游標必須打開,用以通過輸出參數返回。我們可以用一個定義為cursor類型的局部變量引用它。
use pubs
go
/* create a procedure with a cursor output parameter. */
create procedure opencrsr @outcrsr cursor varying output as
set @outcrsr = cursor for
select au_lname
from authors
where au_lname like 's%'
open @outcrsr
go
/* 聲明局部游標. */
declare @crsrvar cursor
/* 將先前的游標賦給局部變量. */
exec opencrsr @outcrsr = @crsrvar output
/* 利用@crsrvar去讀取記錄. */
fetch next from @crsrvar
while (@@fetch_status <> -1)
begin
fetch next from @crsrvar
end
close @crsrvar
deallocate @crsrvar
go
數據庫api并不支持輸出游標參數的存儲過程。一個包含輸出游標參數的存儲過程不能直接被數據庫api執行。這些存儲過程之可以被其他的存儲過程,觸發器,transact-sql 批處理,腳本調用執行。
全局游標在沒有被顯式釋放或連接關閉前一直有效。局部游標默認將在存儲過程,觸發器,批處理結束時釋放,除非它被作為輸出參數輸出。那個局部游標也將在引用它的存儲工程結束時被釋放。