Oracle會創建一個存儲區域,被稱為上下文區域,用於處理SQL語句,其中包含需要處理的語句,例如所有的信息,行數處理,等等。
游標是指向這一上下文的區域。 PL/SQL通過控制光標在上下文區域。游標持有的行(一個或多個)由SQL語句返回。行集合光標保持的被稱為活動集合。
可以命名一個光標,它可以在程序中獲取和處理SQL語句,一次返回的行引用。有兩種類型的游標:
隱式游標
顯式游標
Oracle在一個SQL語句的執行,當沒有顯式游標的語句隱式游標時自動創建。程序員無法控制隱式游標其中的信息。
每當發出一個DML語句(INSERT,UPDATE和DELETE),隱式游標與此語句關聯。對於INSERT操作時,光標保持一個需要插入的數據。對於UPDATE和DELETE操作,光標標識會受到影響的行。
在PL/SQL,可以參考最近的隱式游標的SQL游標,它有類似%FOUND,%ISOPEN,%NOTFOUND,和%ROWCOUNT屬性。在SQL游標有額外的屬性,%BULK_ROWCOUNT和%BULK_EXCEPTIONS,設計用於所有語句中使用。下表提供了最常用的屬性的描述:
任何SQL游標屬性將被訪問,SQL%attribute_name如示例圖所示。
這裡使用我們已經創建,並在前面的章節中使用的CUSTOMERS表。
Select * from customers; +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2000.00 | | 2 | Khilan | 25 | Delhi | 1500.00 | | 3 | kaushik | 23 | Kota | 2000.00 | | 4 | Chaitali | 25 | Mumbai | 6500.00 | | 5 | Hardik | 27 | Bhopal | 8500.00 | | 6 | Komal | 22 | MP | 4500.00 | +----+----------+-----+-----------+----------+
下面的程序將更新表,並通過每個客戶的薪水增加500和使用SQL%ROWCOUNT屬性來確定受影響的行數:
DECLARE total_rows number(2); BEGIN UPDATE customers SET salary = salary + 500; IF sql%notfound THEN dbms_output.put_line('no customers selected'); ELSIF sql%found THEN total_rows := sql%rowcount; dbms_output.put_line( total_rows || ' customers selected '); END IF; END; /
當上述代碼在SQL提示符執行時,它產生了以下結果:
6 customers selected PL/SQL procedure successfully completed.
如果查看customers表中的記錄,會發現各行已更新:
Select * from customers; +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2500.00 | | 2 | Khilan | 25 | Delhi | 2000.00 | | 3 | kaushik | 23 | Kota | 2500.00 | | 4 | Chaitali | 25 | Mumbai | 7000.00 | | 5 | Hardik | 27 | Bhopal | 9000.00 | | 6 | Komal | 22 | MP | 5000.00 | +----+----------+-----+-----------+----------+
顯式游標是程序員定義游標獲得更多的控制權的上下文的區域。顯式游標應在PL/SQL塊的聲明部分中定義。這是創建一個SELECT語句返回多行。
創建顯式游標語法是:
CURSOR cursor_name IS select_statement;
使用顯式游標的工作包括四個步驟:
聲明游標用於初始化在存儲器
打開游標分配內存
獲取游標檢索數據
關閉游標釋放分配的內存
聲明游標定義游標的名稱和相關的SELECT語句。例如:
CURSOR c_customers IS SELECT id, name, address FROM customers;
打開游標游標分配內存,使得它准備取的SQL語句轉換成它返回的行。例如,我們將打開上述定義的游標如下:
OPEN c_customers;
獲取游標涉及一次訪問一行。例如,將獲取行從上面打開的游標,如下所示:
FETCH c_customers INTO c_id, c_name, c_addr;
關閉游標來釋放分配的內存。例如,將關閉前面打開的游標,如下所示:
CLOSE c_customers;
下面是一個完整的例子來說明明確游標的概念:
DECLARE c_id customers.id%type; c_name customers.name%type; c_addr customers.address%type; CURSOR c_customers is SELECT id, name, address FROM customers; BEGIN OPEN c_customers; LOOP FETCH c_customers into c_id, c_name, c_addr; EXIT WHEN c_customers%notfound; dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr); END LOOP; CLOSE c_customers; END; /
當上述代碼在SQL提示符執行時,它產生了以下結果:
1 Ramesh Ahmedabad 2 Khilan Delhi 3 kaushik Kota 4 Chaitali Mumbai 5 Hardik Bhopal 6 Komal MP PL/SQL procedure successfully completed.