SQL Server 7.0 入門(七)

i.??????????????聲明游標
在這一步中,需要指定游標的屬性和根據要求產生的結果集。有兩種方法可以指定一個游標。
形式1??(ansi 92)
declare cursor_name [insensitive] [scroll] cursor
for select_statement
[for {read only | update ][of column_list]}]
形式2
declare cursor_name cursor
[local | global]
[forward_only | scroll]
[static | keyset | dynamic]
[read_only | scroll_locks | optimistic]
for select_statement
[for {read only | update ][of column_list]}]
insensitive關鍵字指明要為檢索到的結果集建立一個臨時拷貝,以后的數據從這個臨時拷貝中獲取。如果在后來游標處理的過程中,原有基表中數據發生了改變,那么它們對于該游標而言是不可見的。這種不敏感的游標不允許數據更改。
scroll關鍵字指明游標可以在任意方向上滾動。所有的fetch選項(first、last、next、relative、absolute)都可以在游標中使用。如果忽略該選項,則游標只能向前滾動(next)。
select_statement指明sql語句建立的結果集。transact sql語句compute、compute by、for browse和into在游標聲明的選擇語句中不允許使用。
read only指明在游標結果集中不允許進行數據修改。
update關鍵字指明游標的結果集可以修改。
of column_list指明結果集中可以進行修改的列。缺省情況下(使用update關鍵字),所有的列都可進行修改。
local關鍵字指明游標是局部的,它只能在它所聲明的過程中使用。
global關鍵字使得游標對于整個連接全局可見。全局的游標在連接激活的任何時候都是可用的。只有當連接結束時,游標才不再可用。
forward_only指明游標只能向前滾動。
static的游標與insensitive的游標是相同的。
keyset指明選取的行的順序。sql server將從結果集中創建一個臨時關鍵字集。如果對數據庫的非關鍵字列進行了修改,則它們對游標是可見的。因為是固定的關鍵字集合,所以對關鍵字列進行修改或新插入列是不可見的。
dynamic指明游標將反映所有對結果集的修改。
scroll_lock是為了保證游標操作的成功,而對修改或刪除加鎖。
optimistic指明哪些通過游標進行的修改或者刪除將不會成功。
注意:
· 如果在select語句中使用了distinct、union、group by語句,且在選擇中包含了聚合表達式,則游標自動為insensitive的游標。
· 如果基表沒有唯一的索引,則游標創建成insensitive的游標。
· 如果select語句包含了order by,而被order by的列并非唯一的行標識,則dynamic游標將轉換成keyset游標。如果keyset游標不能打開,則將轉換成insensitive游標。使用sql ansi-92語法定義的游標同樣如此,只是沒有insensitive關鍵字而已。
???????????????????????ii.??????????????打開游標
打開游標就是創建結果集。游標通過declare語句定義,但其實際的執行是通過open語句。語法如下:
open { { [global] cursor_name } | cursor_variable_name}
global指明一個全局游標。
cursor_name是被打開的游標的名稱。
cursor_variable_name是所引用游標的變量名。該變量應該為游標類型。
在游標被打開之后,系統變量@@cursor_rows可以用來檢測結果集的行數。@@cursor_rows為負數時,表示游標正在被異步遷移,其絕對值(如果@@cursor_rows為-5,則絕對值為5)為當前結果集的行數。異步游標使用戶在游標被完全遷移時仍然能夠訪問游標的結果。
??????????????????????iii.??????????????從游標中取值
在從游標中取值的過程中,可以在結果集中的每一行上來回移動和處理。如果游標定義成了可滾動的(在聲明時使用scroll關鍵字),則任何時候都可取出結果集中的任意行。對于非滾動的游標,只能對當前行的下一行實施取操作。結果集可以取到局部變量中。fetch命令的語法如下:
fetch [next |?prior| first | last | absolute {n | @nvar} | relative {n | @nvar}]
from [global] cursor_name} | cursor_variable_name}
[into @variable_name ][,……n]]
next指明從當前行的下一行取值。
prior指明從當前行的前一行取值。
first是結果集的第一行。
last是結果集的最后一行。
absolute n表示結果集中的第n行,該行數同樣可以通過一個局部變量傳播。行號從0開始,所以n為0時不能得到任何行。
relative n表示要取出的行在當前行的前n行或后n行的位置上。如果該值為正數,則要取出的行在當前行前n行的位置上,如果該值為負數,則返回當前行的后n行。
into @cursor_variable_name表示游標列值存儲的地方的變量列表。該列表中的變量數應該與declare語句中選擇語句所使用的變量數相同。變量的數據類型也應該與被選擇列的數據類型相同。直到下一次使用fetch語句之前,變量中的值都會一直保持。
每一次fetch的執行都存儲在系統變量@@fetch_status中。如果fetch成功,則@@fetch_status被設置成0。@@fetch_status為-1表示已經到達了結果集的一部分(例如,在游標被打開之后,基表中的行被刪除)。@@fetch_status可以用來構造游標處理的循環。
例如:
declare @iname char(20), @fname char(20)
open author_cur
fetch first from author_cur into @iname, @fname
while @@fetch_status = 0
begin
if @fname = ‘albert’
print “found albert ringer”
else
print “other ringer”
fetch next from author_cur into @iname, @fname
end
?????????????????????iv.??????????????關閉游標
close語句用來關閉游標并釋放結果集。游標關閉之后,不能再執行fetch操作。如果還需要使用fetch語句,則要重新打開游標。語法如下:
close [global] cursor_name | cursor_variable_name
???????????????????????v.??????????????釋放游標
游標使用不再需要之后,要釋放游標。deallocate語句釋放數據結構和游標所加的鎖。語法如下:
deallocate [global] cursor_name | cursor_variable_name

???????下面給出游標的一個完整的例子:
???????use master
???????go
???????create procedure sp_buildindexes
???????as
???????declare @tablename sysname, @msg varchar(100), @cmd varchar(100)

???????declare table_cur cursor for
???????select name from sysobjects where type=’u’

???????open table_cur
???????fetch next from table_cur into @tablename
???????
???????while @@fetch_status = 0
???????begin
??????????????if @@fetch_status = -2
?????????????????????continue
??????????????select @msg = “building indexes for table”+@tablename+”…”
??????????????print @msg
??????????????select @cmd = “dbcc dbreindex (‘”+@tablename+”’)”
??????????????exec (@cmd)
??????????????print “????“
??????????????fetch next from table_cur into @tablename
???????end
???????deallocate table_cur
???????go
???????下面的腳本將為pubs數據庫執行sp_buildindexes
???????use pubs
???????go
???????exec ap_buildindexes
???????注意:上面也是創建用戶定義的系統存儲過程的示例。

使用臨時表
???????臨時表是在tempdb中創建的表。臨時表的名稱都以“#”開頭。臨時表的范圍為創建臨時表的連接。因為,臨時表不能在兩個連接之間共享,一旦連接關閉,臨時表就會被丟棄。如果臨時表被創建于存儲過程之中,則臨時表的范圍在存儲過程之中,或者被該存儲過程調用的任何存儲過程之中。如果需要在連接之間共享臨時表,則需要使用全局的臨時表。全局的臨時表以“##”符號開頭,它將一直存在于數據庫中,直到sql server重新啟動。一旦這類臨時表創建之后,所有的用戶都可以訪問到。在臨時表上不能明確地指明權限。???????臨時表提供了存儲中間結果的能力。有時候,臨時表還能通過將一個復雜的查詢分解成兩個查詢而獲得性能的改善。這可以通過首先將第一個查詢的結果存在臨時表中,然后在第二個查詢中使用臨時表來實現。當一個大表中的某個子集在一個在座過程中使用多次時,建議使用臨時表。在這種情況下,在臨時表中保持數據的子集,以在隨后的連接中使用,這樣能大大改善性能。還可以在臨時表中創建索引。?

?以上就是SQL Server 7.0 入門(七)的內容,更多相關內容請關注PHP中文網(www.php.cn)!

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享