什麼是游標 結果集,結果集就是select查詢之後返回的所有行數據的集合。 游標則是處理結果集的一種機制吧,它可以定位到結果集中的某一行,多數據進行讀寫,也可以移動游標定位到你所需要的行中進行操作數據。 一般複雜的存儲過程,都會有游標的出現,他的用處主要有: 定位到結果集中的某一行。 對當前位置的數 ...
什麼是游標
結果集,結果集就是select查詢之後返回的所有行數據的集合。
游標則是處理結果集的一種機制吧,它可以定位到結果集中的某一行,多數據進行讀寫,也可以移動游標定位到你所需要的行中進行操作數據。
一般複雜的存儲過程,都會有游標的出現,他的用處主要有:
- 定位到結果集中的某一行。
- 對當前位置的數據進行讀寫。
- 可以對結果集中的數據單獨操作,而不是整行執行相同的操作。
- 是面向集合的資料庫管理系統和麵向行的程式設計之間的橋梁。
游標使用三步曲:第一步創建游標,第二步打開游標,第三步使用游標。
游標的使用範圍是當前會話。
游標使用
第一步創建游標
語法
--聲明資料庫引用
use testss;
go
--第二種Transact-SQL擴展語法
--Transact-SQL Extended Syntax
declare cursor_name cursor [ local | global ]
[ forward_only | scroll ]
[ static | keyset | dynamic | fast_forward ]
[ read_only | scroll_locks | optimistic ]
[ type_warning ]
for select_statement
[ for update [ of column_name [ ,...n ] ] ]
[;]
語法註釋
--cursor_name
--Transact-SQL伺服器游標定義的名稱。 cursor_name必須符合有關標識符的規則。
--local
--指定該游標的範圍對在其中創建它的批處理、存儲過程或觸發器是局部的。
--該游標名稱僅在這個作用域內有效。在批處理、存儲過程、觸發器或存儲過程output參數中,該游標可由局部游標變數引用。
--output參數用於將局部游標傳遞迴調用批處理、存儲過程或觸發器,它們可在存儲過程終止後給游標變數分配參數使其引用游標。
--除非output參數將游標傳遞迴來,否則游標將在批處理、存儲過程或觸發器終止時隱式釋放。如果output參數將游標傳遞迴來,則游標在最後引用它的變數釋放或離開作用域時釋放。
--global
--指定該游標範圍對連接是全局的。在由此連接執行的任何存儲過程或批處理中,都可以引用該游標名稱。
--該游標僅在斷開連接時隱式釋放。
--備註
--如果global和local參數都未指定,則預設值由“預設為本地游標”資料庫選項的設置控制。
--forward_only
--指定游標只能從第一行滾動到最後一行。fetch next是唯一支持的提取選項。
--如果指定了forward_only而沒有指定static、keyset和dynamic關鍵字,則游標作為dynamic游標進行操作。
--如果未指定forward_only和scroll,則預設為forward_only,
--除非指定了關鍵字static、keyset或dynamic。static、keyset和dynamic游標預設為scroll。
--與odbc和ado等資料庫API不同,static、keyset和dynamic Transact-SQL游標支持forward_only。
--scroll
--指定所有的提取選項(first、last、prior、next、relative和absolute)均可用。 如果未在iso declare cursor中指定scroll,則next是唯一支持的提取選項。
--如果還指定了fast_forward,則無法指定scroll。
--static
--定義一個游標,以創建將由該游標使用的數據的臨時副本。對游標的所有請求都從tempdb中的這一臨時表中得到應答;
--因此,在對該游標進行提取操作時返回的數據中不反映對基表所做的修改,並且該游標不允許修改。
--keyset
--指定當游標打開時,游標中行的成員身份和順序已經固定。對行進行唯一標識的鍵集內置在tempdb內一個稱為keyset的表中。
--備註
--如果查詢引用了至少一個無唯一索引的表,則鍵集游標將轉換為靜態游標。
--對基表中的非鍵值所做的更改(由游標所有者更改或由其他用戶提交)可以在用戶滾動游標時看到。
--其他用戶執行的插入是不可見的(不能通過Transact-SQL伺服器游標執行插入)。如果刪除某一行,則在嘗試提取該行時返回的@@fetch_status為-2。
--從游標外部更新鍵值類似於刪除舊行後再插入新行。具有新值的行不可見,且嘗試提取具有舊值的行時返回的@@fetch_status為 -2。
--如果通過指定where current of子句來通過游標執行更新,則新值可見。
--dynamic
--定義一個游標,以反映在滾動游標時對結果集內的各行所做的所有數據更改。
--行的數據值、順序和成員身份在每次提取時都會更改。動態游標不支持absolute提取選項。
--fast_forward
--指定已啟用了性能優化的fast_forward和read_only游標。如果還指定了scroll或for_update,則無法指定fast_forward。
--備註
--可以在相同的declare cursor語句中使用fast_forward和forward_only。
--read_only
--禁止通過該游標進行更新。無法在update或delete語句的where current of子句中引用游標。
--該選項優先於要更新的游標的預設功能。
--scroll_locks
--指定通過游標進行的定位更新或刪除一定會成功。將行讀入游標時SQLServer將鎖定這些行,以確保隨後可對它們進行修改。
--如果還指定了fast_forward或static,則無法指定scroll_locks。
--optimistic
--指定如果行自讀入游標以來已得到更新,則通過游標進行的定位更新或定位刪除不成功。
--當將行讀入游標時,SQLServer不鎖定行。
--相反,它使用timestamp列值的比較,或者如果表沒有timestamp列則使用校驗和值,以確定將行讀入游標後是否已修改該行。
--如果已修改該行,嘗試進行的定位更新或定位刪除將失敗。如果還指定了fast_forward,則無法指定optimistic。
--type_warning
--指定如果游標從所請求的類型隱式轉換為另一種類型,則向客戶端發送警告消息。
--select_statement
--定義游標結果集的標準select語句。在游標聲明的select_statement中不允許使用關鍵字compute、compute by、for browse和into。
--備註
--可以在游標聲明中使用查詢提示;但如果還使用for update of子句,請在for update of之後指定option(<query_hint>)。
--如果select_statement中的子句與所請求的游標類型的功能有衝突,則SQLServer會將游標隱式轉換為其他類型。有關詳細信息,請參閱“隱式游標轉換”。
--for update [of column_name [,...n]]
--定義游標中可更新的列。 如果提供了of <column_name> [, <... n>],則只允許修改所列出的列。 如果指定了update,但未指定列的列表,則除非指定了read_only併發選項,否則可以更新所有的列。
示例
declare firstcursor cursor
scroll
static
read_only
type_warning
for
select id,name from test1
--for update;
示例結果
第二步打開游標
語法
open { { [ global ] cursor_name } | cursor_variable_name }
語法解析
--global
--指定cursor_name是指全局游標。
--cursor_name
--已聲明的游標的名稱。當同時存在以cursor_name作為名稱的全局游標和局部游標時,如果指定global,則cursor_name是指全局游標;否則,cursor_name是指局部游標。
--cursor_variable_name
--游標變數的名稱,該變數引用一個游標。
示例
open firstcursor;
示例結果
第三步使用游標
語法
fetch [ [ next | prior | first | last | absolute { n | @nvar } | relative { n | @nvar } ] from ]
{ { [ global ] cursor_name } | @cursor_variable_name }
[ into @variable_name [ ,...n ] ]
語法註釋
--next
--緊跟當前行返回結果行,並且當前行遞增為返回行。如果fetch next為對游標的第一次提取操作,則返回結果集中的第一行。next為預設的游標提取選項。
--prior
--返回緊鄰當前行前面的結果行,並且當前行遞減為返回行。如果fetch prior為對游標的第一次提取操作,則沒有行返回並且游標置於第一行之前。
--first
--返回游標中的第一行並將其作為當前行。
--last
--返回游標中的最後一行並將其作為當前行。
--absolute { n| @nvar}
--如果 n 或 @nvar 為正,則返回從游標起始處開始向後的第 n 行,並將返回行變成新的當前行。
--如果 n 或 @nvar 為負,則返回從游標末尾處開始向前的第 n 行,並將返回行變成新的當前行。
--如果 n 或 @nvar 為 0,則不返回行。 n 必須是整數常量,並且 @nvar 必須是 smallint、tinyint 或 int。
--relative { n| @nvar}
--如果 n 或 @nvar 為正,則返回從當前行開始向後的第 n 行,並將返回行變成新的當前行。
--如果 n 或 @nvar 為負,則返回從當前行開始向前的第 n 行,並將返回行變成新的當前行。
--如果 n 或 @nvar 為 0,則返回當前行。 在對游標進行第一次提取時,
--如果在將 n 或 @nvar 設置為負數或 0 的情況下指定fetch relative,則不返回行。 n 必須是整數常量,並且 @nvar 必須是 smallint、tinyint 或 int。
--global
--指定 cursor_name 是指全局游標。
--cursor_name
--要從中進行提取的開放游標的名稱。 當同時存在以 cursor_name 作為名稱的全局游標和局部游標時,
--如果指定global,則 cursor_name 指全局游標,如果未指定 global,則指局部游標。
--@cursor_variable_name
--游標變數名,引用要從中進行提取操作的打開的游標。
--into @variable_name[ ,...n]
--允許將提取操作的列數據放到局部變數中。 列表中的各個變數從左到右與游標結果集中的相應列相關聯。
--各變數的數據類型必須與相應的結果集列的數據類型匹配,或是結果集列數據類型所支持的隱式轉換。 變數的數目必須與游標選擇列表中的列數一致。
示例
declare @id nvarchar(50),@name nvarchar(50);
fetch first from firstcursor into @id,@name;
select @id,@name;
示例結果