SQL游標
隱含游標:專門處理SELECT INTO、INSERT、UPDATE以及DELETE語句。
顯示游標:用于處理多行的SELECT語句。
當在PL/SQL塊中執行INSERT、UPDATE及DELETE語句時,為了取得DML語句作用的結果,需要使用SQL游標屬性。
第一,游標的4種屬性
1. SQL%ISOPEN
該屬性永遠都是false,沒有實際意義。
2. SQL%FOUND
語句是否操作成功。當SQL語句有作用行時為TRUE.
3. SQL%NOTFOUND
LOOP
FETCH emp_cursor INTO v_name, v_deptno;
EXIT WHEN emp_cursor%NOTFOUND;
...
END LOOP;
4. SQL%ROWCOUNT
返回SQL語句所作用的總計行數。
該屬性用于返回已提取的實際行數。
第二,顯示游標專用于處理SELECT語句返回的多行數據。
- 定義游標:
CURSOR cursor_name IS select_statement;
- 打開游標:
open cursor_name;
- 提到數據:
FETCH cursor_name INTO var1[, var2, ...];
- 關閉游標:
CLOSE cursor_name;
例子:
DECLARE
CURSOR category_cursor
IS
SELECT *
FROM tb_out_service t
WHERE t.servicename LIKE '長沙%';
TYPE category_table_type IS TABLE OF tb_out_service%ROWTYPE
INDEX BY BINARY_INTEGER;
category_table category_table_type;
i INT;
BEGIN
OPEN category_cursor;
LOOP
i := category_cursor%ROWCOUNT + 1;
FETCH category_cursor
INTO category_table (i);
EXIT WHEN category_cursor%NOTFOUND;
DBMS_OUTPUT.put_line ( RPAD (category_table (i).serviceid, 30)
|| ' '
|| category_table (i).servicename
);
END LOOP;
CLOSE category_cursor;
END;
第三,游標FOR循環
語法:
FOR record_name IN cursor_name LOOP
statement;
...
END LOOP;
注意:當使用游標FOR循環時,既可以在定義部分定義游標,也可以直接在FOR循環中使用SELECT語句。
第四,參數游標
CURSOR cursor_name(parameter_name datatype) is select_statement;
OPEN cursor_name(parameter_value)
注意:
定義參數只能指定數據類型,不能指定長度。
另外,應該在游標的select語句的where子句中引用游標參數,否則失去了定義參數游標的意義。
---------------------------------------------------------------------------------------------------------------------
DECLARE
CURSOR category_cursor (NAME VARCHAR2)
IS
SELECT *
FROM tb_out_service t
WHERE t.servicename LIKE NAME || '%';
BEGIN
FOR category_record IN category_cursor ('吉首')
LOOP
DBMS_OUTPUT.put_line ( RPAD (category_record.serviceid, 30)
|| ' '
|| category_record.servicename
);
END LOOP;
END;
第五,更新或刪除游標行
語法:
CURSOR cursor_name IS select_statement
FOR UPDATE [OF column_reference] [NOWAIT];
UPDATE table_name SET column=.. WHERE CURRENT OF cursor_name;
DELETE FROM table_name WHERE CURRENT OF cursor_name;
注意:
1. OF子句的格式:column_reference為table_name.column_name
2. WHERE CURRENT OF cursor_name, 更新或者刪除游標所在行的數據。
3. 在使用游標更新或刪除數據時,定義游標必須帶有FOR UPDATE子句,并且在更新或者刪除游標時必須帶有WHERE CURRENT OF 子句。
當查詢語句涉及到多張表時,如果不帶有OF子句,會在多張表上同時加鎖,如果只在特定的表上加鎖,需要帶有OF子句。
DECLARE
CURSOR category_cursor (NAME VARCHAR2)
IS
SELECT *
FROM tb_out_service t
WHERE t.servicename LIKE NAME || '%'
FOR UPDATE OF t.querystr;
v_name CONSTANT VARCHAR2 (20) := '長沙';
BEGIN
FOR category_record IN category_cursor (v_name)
LOOP
IF INSTR (category_record.servicename, v_name || '——') <> 1
THEN
DBMS_OUTPUT.put_line ( 'delete: '
|| RPAD (category_record.serviceid, 30)
|| ' '
|| category_record.servicename
);
DELETE FROM tb_out_service
WHERE CURRENT OF category_cursor;
ELSE
DBMS_OUTPUT.put_line ( 'upate: '
|| RPAD (category_record.serviceid, 30)
|| ' '
|| category_record.servicename
);
UPDATE tb_out_service t
SET t.querystr = v_name || '——' || t.servicename
WHERE CURRENT OF category_cursor;
END IF;
END LOOP;
END;
第六, 游標變量
游標變量是基于REF CURSOR類型所定義的變量,它實際上是指向內存地址的指針。顯式游標只能定義靜態游標,而游標變量可以在打開時指定其所對應的SELECT語句,從而實現動態游標。
- 定義游標:
TYPE ref_type_name IS REF CURSOR [RETURN return_type];
cursor_variable ref_type_name;
- 打開游標:
OPEN cursor_name FOR select_statement;
- 提到數據:
FETCH cursor_variable INTO var1[, var2, ...];
- 關閉游標:
CLOSE cursor_variable;
注意:
不能在遠程子程序中使用游標變量。
當指定子查詢時,不能帶有FOR UPDATE子句。
當指定RETURN子句時,返回類型必須使用PL/SQL記錄類型。
例子:
DECLARE
TYPE category_cursor_type IS REF CURSOR
RETURN tb_out_service%ROWTYPE;
category_cursor category_cursor_type;
category_record tb_out_service%ROWTYPE;
v_name CONSTANT VARCHAR2 (40) := '長沙';
BEGIN
OPEN category_cursor FOR
SELECT *
FROM tb_out_service t
WHERE t.servicename LIKE v_name || '%';
LOOP
FETCH category_cursor
INTO category_record;
EXIT WHEN category_cursor%NOTFOUND;
DBMS_OUTPUT.put_line ( RPAD (category_record.serviceid, 30)
|| ' '
|| category_record.servicename
);
END LOOP;
END;
posted on 2009-03-17 11:07 JavaBegger 閱讀(631) 評論(0) 編輯 收藏