Transact-SQL 資料指標
Transact-SQL 資料指標主要用於預存程序、觸發程序與 Transact-SQL 指令碼,以構成供其他 Transact-SQL 陳述式使用的結果集內容。
在預存程序或觸發程序中使用 Transact-SQL 資料指標的典型程序為:
宣告 Transact-SQL 變數以包含資料指標所傳回的資料。為每個結果集資料行宣告一個變數。宣告夠大的變數足以儲存資料行所傳回的值,並使用可以從資料行的資料類型隱含轉換的資料類型。
利用 DECLARE CURSOR 陳述式使 Transact-SQL資料指標與 SELECT 陳述式建立關聯。DECLARE CUROSR 陳述式同時定義資料指標的特性,例如資料指標名稱,以及資料指標是屬於唯讀或順向 (ForwardOnly)。
使用 OPEN 陳述式執行 SELECT 陳述式並填入資料指標。
使用 FETCH INTO 陳述式提取個別的資料列,並將每個資料行的資料移動到指定的變數。其他的 Transact-SQL 陳述式就可以參考這些變數,以存取提取的資料值。Transact-SQL 資料指標不支援提取資料列的區塊。
當您完成資料指標時,請使用 CLOSE 陳述式。關閉資料指標將可釋放一些資源,例如,資料指標的結果集和目前資料列上的鎖定,但如果您重新發出 OPEN 陳述式,資料指標結構仍然可用來處理。因為資料指標仍然存在,您無法在此時重複使用資料指標名稱。DEALLOCATE 陳述式將完全釋放所有配置到資料指標的資源,包含資料指標名稱。在取消配置資料指標後,您必須發出 DECLARE 陳述式來重建資料指標。
監視 Transact-SQL 資料指標活動
您可以使用 sp_cursor_list 系統預存程序取得目前連線下可見的資料指標清單,並以 sp_describe_cursor、sp_describe_cursor_columns 和 sp_describe_cursor_tables 決定資料指標應具備哪些特性。
開啟資料指標後,@@CURSOR_ROWS 函數,或由 sp_cursor_list 或sp_describe_cursor 傳回的cursor_rows 資料行會指出資料指標中的資料行數目。
在每個 FETCH 陳述式後,會將 @@FETCH_STATUS 更新以反映上一個提取的狀態。您也可以從 sp_describe_cursor 傳回的 fetch_status 資料行來取得此狀態資訊。@@FETCH_STATUS 會報告的狀況諸如提取資料指標中第一或最後一個之外的資料列。@@FETCH_STATUS 對連接而言是全域的,而且針對該連接所開啟的任何資料指標上的每個提取都會重新設定它。如果您必須在稍後瞭解狀態,請在連接上執行另一個陳述式之前,先將 @FETCH\_STATUS 儲存到使用者變數中。即使下一個陳述式不是 FETCH,它也有可能是 INSERT、UPDATE 或 DELETE,可引發包含 FETCH 陳述式的觸發程序來重設 @@FETCH_STATUS。sp_describe_cursor 所傳回的 fetch_status 資料行是關於指定資料指標的狀態,而且不會受到參考其他資料指標的 FETCH 陳述式之影響。不過,sp_describe_cursor 會受到參考相同資料指標的 FETCH 陳述式之影響,所以仍需謹慎使用。
FETCH 作業完成之後,資料指標會停在擷取的資料列上。所擷取的資料列即是目前資料行。如果資料指標未宣告為唯讀資料指標,您可執行具有 WHERE CURRENT OF cursor_name 子句的 UPDATE 或 DELETE 陳述式來修改目前的資料列。
DECLARE CURSOR 陳述式所指定的 Transact-SQL 資料指標名稱可以是全域或區域。全域資料指標名稱可供執行相同連接的任何批次、預存程序或觸發程序參考。區域資料指標無法在宣告資料指標的批次、預存程序或觸發程序之外被參考。觸發程序和預存程序中的區域資料指標也因此受到保護,無法由預存程序或觸發程序之外的非預期參考所使用。
使用資料指標變數
MicrosoftSQL Server 也支援使用 cursor 資料類型的變數。資料指標可以用下列任一種方式與 cursor 變數產生關聯:
/* Use DECLARE @local_variable, DECLARE CURSOR and SET. */
DECLARE @MyVariable CURSOR
DECLARE MyCursor CURSOR FOR
SELECT LastName FROM AdventureWorks.Person.Contact
SET @MyVariable = MyCursor
GO
/* Use DECLARE @local_variable and SET */
DECLARE @MyVariable CURSOR
SET @MyVariable = CURSOR SCROLL KEYSET FOR
SELECT LastName FROM AdventureWorks.Person.Contact;
DEALLOCATE MyCursor;
在資料指標與 cursor 變數產生關聯後,cursor 變數可取代 Transact-SQL 資料指標陳述式中的資料指標名稱。也可以指派 cursor 資料類型給預存程序輸出參數,並與資料指標關聯。這可讓預存程序以控制的方式來公開區域資料指標。
參考 Transact-SQL 資料指標
Transact-SQL 資料指標名稱和變數僅可供 Transact-SQL 陳述式參考,至 於 OLE DB、ODBC 和 ADO 的 API 函數則無法參考它們。例如,如果您在 Transact-SQL 資料指標上宣告 DECLARE CURSOR 和 OPEN,就無法使用 ODBC SQLFetch 或 SQLFetchScroll 函數提取 Transact-SQL 資料指標的資料列。需要資料指標處理和使用這些 API 的應用程式,應該使用支援內建資料庫 API 的資料指標來取代 Transact-SQL 資料指標。
您可以在應用程式中使用 Transact-SQL 資料指標,即使用 FETCH 並將 FETCH 所傳回的每個資料行繫結至程式變數。不過,Transact-SQL FETCH 不支援批次,所以這是將資料傳回應用程式最有效的方式。提取每個資料列需要往返於伺服器。最有效率的方法為使用內建於資料庫 API 的資料指標功能,可支援提取資料列的批次。
當在預存程序和觸發程序中包含 Transact-SQL 資料指標時,是極為有效率的。這是因為所需的一切均已在伺服器上編譯至一個執行計畫中,所以完全沒有提取資料列相關的網路流量。
Transact-SQL 資料指標與 SET 選項。
在 SQL Server 中,當發出 FETCH 陳述式時,若在開啟資料指標之前有變更值,就會引發錯誤。只要有任何下列影響計畫的選項,或是索引檢視及計算資料行所需的選項,就會發生此錯誤。若要避免這種錯誤,請勿在開啟資料指標時變更 SET 選項。
影響計畫的選項 |
ARITHABORT NUMERIC_ROUNDABORT FORCEPLAN QUOTED_IDENTIFIER ANSI_NULL_DFLT_ON ANSI_NULL_DFLT_OFF ANSI_WARNINGS ANSI_PADDING ANSI_NULLS CONCAT_NULL_YIELDS_NULL DATEFIRST DATEFORMAT LANGUAGE TEXTSIZE |
索引檢視和計算資料行 |
ANSI_NULLS ANSI_PADDING ANSI_WARNINGS ARITHABORT (在 80 或較低的相容性層級下) CONCAT_NULL_YIELDS_NULL QUOTED_IDENTIFIER NUMERIC_ROUNDABORT |
在 SQL Server 2000 中,對 ANSI_NULLS 與 QUOTED_IDENTIFIER 的變更並不會引發錯誤,但其他的變更就會引發錯誤。