plsql存过声明游标_plsql--游标用法
1.游標(biāo)概念
在 PL/SQL 塊中執(zhí)行 SELECT、INSERT、DELETE 和 UPDATE 語句時,ORACLE 會在內(nèi)存中為其分配上下文區(qū)(Context Area),即緩沖區(qū)。游標(biāo)是指向該區(qū)的一個指針,或
是命名一個工作區(qū)(Work Area),或是一種結(jié)構(gòu)化數(shù)據(jù)類型。它為應(yīng)用等量齊觀提供了一種對具有多行數(shù)據(jù)查詢結(jié)果集中的每一行數(shù)據(jù)分別進(jìn)行單獨處理的方法,是設(shè)計嵌入式
SQL 語句的應(yīng)用程序的常用編程方式。
在每個用戶會話中,可以同時打開多個游標(biāo),其數(shù)量由數(shù)據(jù)庫初始化參數(shù)文件中的
OPEN_CURSORS 參數(shù)定義。
對于不同的 SQL 語句,游標(biāo)的使用情況不同:
非查詢語句--》 隱式的
結(jié)果是單行的查詢語句 --》隱式的或顯示的
結(jié)果是多行的查詢語句--》 顯示的
2.處理顯示游標(biāo)
2.1顯示游標(biāo)處理的4個步驟
1.定義/ / 聲明 游標(biāo):就是定義一個游標(biāo)名,以及與其相對應(yīng)的 SELECT 語句。
格式:
CURSOR cursor_name[(parameter[, parameter]…)]
[RETURN datatype]
IS
select_statement;
注意:1.游標(biāo)參數(shù)只能為輸入?yún)?shù)
2.在指定數(shù)據(jù)類型時,不能使用長度約束
3.[RETURN datatype]是可選的,表示游標(biāo)返回數(shù)據(jù)的數(shù)據(jù)。如果選擇,則應(yīng)該嚴(yán)格與 select_statement 中的選擇列表在次序和數(shù)據(jù)類型上匹配。一般是記錄數(shù)據(jù)類型或帶“%ROWTYPE”的數(shù)據(jù)。
2.打開游標(biāo)
就是執(zhí)行游標(biāo)所對應(yīng)的 SELECT 語句,將其查詢結(jié)果放入工作區(qū),并且指
針指向工作區(qū)的首部,標(biāo)識游標(biāo)結(jié)果集合。如果游標(biāo)查詢語句中帶有 FOR UPDATE 選
項,OPEN 語句還將鎖定數(shù)據(jù)庫表中游標(biāo)結(jié)果集合對應(yīng)的數(shù)據(jù)行。
格式:OPEN cursor_name[([parameter =>] value[, [parameter =>] value]…)];
3.提取游標(biāo)
就是檢索結(jié)果集合中的數(shù)據(jù)行,放入指定的輸出變量中。
格式:FETCH cursor_name INTO {variable_list | record_variable };
執(zhí)行 FETCH 語句時,每次返回一個數(shù)據(jù)行,然后自動將游標(biāo)移動指向下一個數(shù)據(jù)行。當(dāng)
檢索到最后一行數(shù)據(jù)時,如果再次執(zhí)行 FETCH 語句,將操作失敗,并將游標(biāo)屬性
%NOTFOUND 置為 TRUE。所以每次執(zhí)行完 FETCH 語句后,檢查游標(biāo)屬性%NOTFOUND
就可以判斷 FETCH 語句是否執(zhí)行成功并返回一個數(shù)據(jù)行,以便確定是否給對應(yīng)的變量賦了
值。
4.關(guān)閉游標(biāo)
當(dāng)提取和處理完游標(biāo)結(jié)果集合數(shù)據(jù)后,應(yīng)及時關(guān)閉游標(biāo),以釋放該游標(biāo)所占
用的系統(tǒng)資源,并使該游標(biāo)的工作區(qū)變成無效,不能再使用 FETCH 語句取其中數(shù)據(jù)。
關(guān)閉后的游標(biāo)可以使用 OPEN 語句重新打開。
格式:CLOSE cursor_name;
注意:定義的游標(biāo)不能有 INTO 子句。
游標(biāo)屬性
游標(biāo)屬性 屬性作用
Cursor_name%FOUND 布爾型屬性,當(dāng)最近一次提取游標(biāo)操作 FETCH成功則為 TRUE,否則為 FALSE;
Cursor_name%NOTFOUND 布爾型屬性,與%FOUND 相反;
Cursor_name%ISOPEN 布爾型屬性,當(dāng)游標(biāo)已打開時返回 TRUE;
Cursor_name%ROWCOUNT 數(shù)字型屬性,返回已從游標(biāo)中讀取的記錄數(shù)。
2.2使用案例
--普通游標(biāo)
declare
cursor emp_cursor1 is
select ename,sal from emp where sal < 1000;
v_name emp.ename%type;
v_sal emp.sal%type;
begin
open emp_cursor1;
loop
fetch emp_cursor1
into v_name,v_sal;
exit when emp_cursor1%notfound;
dbms_output.put_line(v_name || '---' || v_sal);
--dbms_output.put_line('isOpen:'||emp_cursor1%isopen); --查看游標(biāo)狀態(tài)
end loop;
close emp_cursor1;
end;
--游標(biāo)傳參
declare
cursor emp_cursor2(cursor_sal number default 2000) is --(此處的參數(shù)是默認(rèn)參數(shù),后面可以重新設(shè)置,此默認(rèn)值失效)
select ename,sal from emp where sal >= cursor_sal;
v_name emp.ename%type;
v_sal emp.sal%type;
begin
open emp_cursor2(cursor_sal=>3000); --(重新設(shè)置參數(shù)值)
loop
fetch emp_cursor2
into v_name,v_sal;
exit when emp_cursor2%notfound;
dbms_output.put_line(v_name || '---' || v_sal);
end loop;
dbms_output.put_line('rowcount:'||emp_cursor2%rowcount); --(游標(biāo)記錄數(shù))
close emp_cursor2;
end;
--if...then(給工資低于2000的員工加薪1元)
declare
cursor emp_cursor3 is
select ename, sal, empno from emp;
v_no emp.empno%type;
v_name emp.ename%type;
v_sal emp.sal%type;
begin
open emp_cursor3;
loop
fetch emp_cursor3
into v_name, v_sal, v_no;
exit when emp_cursor3%notfound;
if v_sal <= 2000 then
update emp set sal = sal + 1 where empno = v_no;
dbms_output.put_line(v_name || '---' || v_sal);
end if;
end loop;
dbms_output.put_line('rowcount:' || emp_cursor3%rowcount);
close emp_cursor3;
end;
--有參數(shù)有返回值的游標(biāo)(記錄類型)
declare
type emp_record_type is record(
v_no emp.empno%type,
v_name emp.ename%type,
v_sal emp.sal%type);
v_emp_record emp_record_type;
cursor emp_cursor4(dept_no number) return emp_record_type is
select empno, ename, sal from emp where deptno = dept_no;
begin
open emp_cursor4(dept_no=>20);
loop
fetch emp_cursor4
into v_emp_record;
if emp_cursor4%found then
dbms_output.put_line(v_emp_record.v_name || '---' ||
v_emp_record.v_sal);
else
dbms_output.put_line('已經(jīng)處理完結(jié)果集');
exit;
end if;
end loop;
close emp_cursor4;
end;
--for循環(huán)格式游標(biāo)
declare
cursor emp_cursor5 is
select ename, sal from emp;
begin
for v_sal in emp_cursor5 loop
dbms_output.put_line(v_sal.ename || '--***--' || v_sal.sal);
end loop;
end;
--for循環(huán)格式游標(biāo)帶參數(shù)
declare
cursor emp_cursor5(dept_no number) is
select ename, sal from emp where deptno=dept_no;
begin
for v_sal in emp_cursor5(30) loop
dbms_output.put_line(v_sal.ename || '--***--' || v_sal.sal);
end loop;
end;
--for循環(huán)子查詢方式游標(biāo)
begin
for v_sal in (select ename, sal from emp where deptno=20) loop
dbms_output.put_line(v_sal.ename || '--***--' || v_sal.sal);
end loop;
end;
3.處理隱式游標(biāo)
顯式游標(biāo)主要是用于對查詢語句的處理,尤其是在查詢結(jié)果為多條記錄的情況下;而對
于非查詢語句,如修改、刪除操作,則由 ORACLE 系統(tǒng)自動地為這些操作設(shè)置游標(biāo)并創(chuàng)建
其工作區(qū),這些由系統(tǒng)隱含創(chuàng)建的游標(biāo)稱為隱式游標(biāo),隱式游標(biāo)的名字為 SQL,這是由
ORACLE 系統(tǒng)定義的。對于隱式游標(biāo)的操作,如定義、打開、取值及關(guān)閉操作,都由 ORACLE
系統(tǒng)自動地完成,無需用戶進(jìn)行處理。用戶只能通過隱式游標(biāo)的相關(guān)屬性,來完成相應(yīng)的操
作。在隱式游標(biāo)的工作區(qū)中,所存放的數(shù)據(jù)是與用戶自定義的顯示游標(biāo)無關(guān)的、最新處理的
一條 SQL 語句所包含的數(shù)據(jù)。
格式調(diào)用為: SQL%
隱式游標(biāo)屬性
屬性 值 SELECT INSERT UPDATE DELETE
SQL%ISOPEN FALSE FALSE FALSE FALSE
SQL%FOUND TRUE 有結(jié)果 成功 成功
SQL%FOUND FALSE 沒結(jié)果 失敗 失敗
SQL%NOTFUOND TRUE 沒結(jié)果 失敗 失敗
SQL%NOTFOUND FALSE 有結(jié)果 成功 失敗
SQL%ROWCOUNT 返回行數(shù),只為 1插入的行數(shù) 修改的行數(shù) 刪除的行數(shù)
使用案例:
DECLARE
v_rows NUMBER;
BEGIN
--更新數(shù)據(jù)
UPDATE emp SET sal = 30000
WHERE deptno = 20;
--獲取默認(rèn)游標(biāo)的屬性值
v_rows := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('更新了'||v_rows||'個雇員的工資');
--回退更新,以便使數(shù)據(jù)庫的數(shù)據(jù)保持原樣
ROLLBACK;
END;
總結(jié)
以上是生活随笔為你收集整理的plsql存过声明游标_plsql--游标用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Matlab 输入输出操作
- 下一篇: STM32实现水下四旋翼(三)通信任务—