1. 程式人生 > >儲存過程中輸出引數為遊標的時候怎麼處理

儲存過程中輸出引數為遊標的時候怎麼處理

http://msdn.microsoft.com/zh-cn/library/ms175498(v=sql.90).aspx

Transact-SQL 儲存過程只能將 cursor 資料型別用於 OUTPUT 引數。如果為某個引數指定了 cursor 資料型別,也必須指定 VARYING 和 OUTPUT 引數。如果為某個引數指定了 VARYING 關鍵字,則資料型別必須是 cursor,並且必須指定 OUTPUT 關鍵字。

ms175498.note(zh-cn,SQL.90).gif注意:
cursor 資料型別不能通過資料庫 API(例如 OLE DB、ODBC、ADO 和 DB-Library)繫結到應用程式變數上。因為必須先繫結 OUTPUT 引數,應用程式才可以執行儲存過程,所以帶有 cursor
 OUTPUT 引數的儲存過程不能通過資料庫 API 呼叫。只有將 cursor OUTPUT 變數分配給 Transact-SQL 區域性 cursor 變數時,才可以通過 Transact-SQL 批處理、儲存過程或觸發器呼叫這些過程。

在執行過程時,以下規則適用於 cursor 輸出引數:

  • 對於只進遊標,遊標的結果集中返回的行只是那些儲存過程執行結束時處於或超出遊標位置的行,例如: 
    • 在過程中的名為 RS 的 100 行結果集上開啟一個非滾動遊標。
    • 過程提取結果集 RS 的頭 5 行。
    • 過程返回到其呼叫者。
    • 返回到呼叫者的結果集 RS 由 RS 的第 6 到 100 行組成,呼叫者中的遊標處於 RS 的第一行之前。
  • 對於只進遊標,如果儲存過程完成後,遊標位於第一行的前面,則整個結果集將返回給呼叫批處理、儲存過程或觸發器。返回時,遊標將位於第一行的前面。
  • 對於只進遊標,如果儲存過程完成後,遊標的位置超出最後一行的結尾,則為呼叫批處理、儲存過程或觸發器返回空結果集。 
    ms175498.note(zh-cn,SQL.90).gif注意:
    空結果集與空值不同。
  • 對於可滾動遊標,在儲存過程執行結束時,結果集中的所有行均會返回給呼叫批處理、儲存過程或觸發器。返回時,遊標保留在過程中最後一次執行提取時的位置。
  • 對於任意型別的遊標,如果遊標關閉,則將空值傳遞迴呼叫批處理、儲存過程或觸發器。如果將遊標指派給一個引數,但該遊標從未開啟過,也會出現這種情況。 
    ms175498.note(zh-cn,SQL.90).gif注意:
    關閉狀態只有在返回時才有影響。例如,可以在過程中關閉遊標,稍後再開啟遊標,然後將該遊標的結果集返回給呼叫批處理、儲存過程或觸發器。
示例

在下面的示例中,建立了使用 cursor 資料型別指定輸出引數 @currency_cursor 的儲存過程。然後在批處理中呼叫儲存過程

首先,建立以下過程,在 Currency 表上宣告並開啟一個遊標。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'dbo.uspCurrencyCursor', 'P' ) IS NOT NULL
    DROP PROCEDURE dbo.uspCurrencyCursor;
GO
CREATE PROCEDURE dbo.uspCurrencyCursor 
    @CurrencyCursor CURSOR VARYING OUTPUT
AS
    SET NOCOUNT ON;
    SET @CurrencyCursor = CURSOR
    FORWARD_ONLY STATIC FOR
      SELECT CurrencyCode, Name
      FROM Sales.Currency;
    OPEN @CurrencyCursor;
GO

接下來,執行一個批處理,宣告一個區域性遊標變數,執行上述過程以將遊標賦值給區域性變數,然後從該遊標提取行。

USE AdventureWorks;
GO
DECLARE @MyCursor CURSOR;
EXEC dbo.uspCurrencyCursor @CurrencyCursor = @MyCursor OUTPUT;
WHILE (@@FETCH_STATUS = 0)
BEGIN;
     FETCH NEXT FROM @MyCursor;
END;
CLOSE @MyCursor;
DEALLOCATE @MyCursor;
GO