1、遊標定義
1.遊標是查詢結果集的平面化展現,經過遊標方便定位到結果集中某個特定的行。
2.遊標的分類
顯示遊標:即用戶自定義遊標,專門用於處理select語句返回的多行數據
隱式遊標:系統自動定義的遊標,記錄集只有單行數據,用於處理select into 和DML語句
3.遊標使用的通常過程:
顯示遊標:聲明, 打開, 讀取, 關閉
隱式遊標:直接使用讀取,聲明、打開、關閉都是系統自動進行的
4顯示遊標的過程描述
a.聲明遊標
CURSOR cursor_name IS select_statement
如:CURSOR emp_cur IS SELECT empno,ename,job,sal FROM scott.emp;
b.打開遊標,打開遊標則執行對應的select語句,將對應的結果集存放到遊標當中
OPEN cursor_name
c.獲取數據,提取單行數據,須要配合循環語句來使用,提取多行數據,collect爲集合變量
FETCH cursor_name INTO var_name1,...var_name2 ;
FETCH cursor_name BULK COLLECT INTO collect1,collect2,...[LIMIT rows];
d.關閉遊標
CLOSE cursor_name
5.顯示遊標的5個屬性
cursor_name%ISOPEN --遊標是否打開
cursor_name%FOUND --最近的FETCH是否提取到數據
cursor_name%NOTFOUND --最近的FETCH是否沒有提取到數據
cursor_name%ROWCOUNT --返回到目前爲止,已經從遊標緩衝區中提取到數據的行數
2、遊標使用
1.輸入job,輸出ename,sal值
declare
v_name emp.ename%type;
v_sal emp.sal%type;
cursor cur_one is select ename,sal from emp where job ='&input';
begin
open cur_one;
dbms_output.put_line('ename sal');
loop
fetch cur_one into v_name,v_sal;
exit when (cur_one%notfound);
dbms_output.put_line(v_name||' '||v_sal);
end loop;
close cur_one;
end;
2.使用遊標統必定義變量類型
declare
cursor cur_one is select ename,sal,job,mgr,hiredate,comm from emp where job ='&input';
v_cur_col cur_one%rowtype;
begin
open cur_one;
dbms_output.put_line('ename sal');
loop
fetch cur_one into v_cur_col;
exit when (cur_one%notfound);
dbms_output.put_line(v_cur_col.ename||' '||v_cur_col.sal);
end loop;
close cur_one;
end;
3.遊標FOR循環
遊標FOR循環是爲了簡化遊標使用過程而設計的。使用遊標FOR循環檢索遊標時,遊標的打開、數據提取、數據是否檢
索到的判斷與遊標的關閉都是ORACLE系統自動進行的。
--顯式
DECLARE
CURSOR CURSOR_006 IS
SELECT ENAME, HIREDATE FROM EMP WHERE SAL < &SAL;
BEGIN
DBMS_OUTPUT.PUT_LINE('ename hiredate');
FOR V_CUR IN CURSOR_006 LOOP
DBMS_OUTPUT.PUT_LINE(V_CUR.ENAME || ' ' || V_CUR.HIREDATE);
END LOOP;
END;
--隱式
BEGIN
DBMS_OUTPUT.PUT_LINE('ename hiredate');
FOR V_CUR IN (SELECT ENAME, HIREDATE FROM EMP WHERE SAL < &SAL) LOOP
DBMS_OUTPUT.PUT_LINE(V_CUR.ENAME || ' ' || V_CUR.HIREDATE);
END LOOP;
END;
3、記錄
是一個或多個字段且擁有數據類型的集合體,相似於表的數據結構,定義了PL/SQL記錄類型以後,能夠定義
PL/SQL記錄變量,多用於簡化單行多列的數據處理。
1.記錄的定義
a.自定義記錄成員
TYPE TYPE_NAME IS RECORD
(field_name1 datatype1 [NOT NULL] [ := DEFAULT EXPRESSION],
field_name2 datatype2 [NOT NULL] [ := DEFAULT EXPRESSION],
...
field_nameN datatypeN [NOT NULL] [ := DEFAULT EXPRESSION]);
record_name TYPE_NAME;
b.參照數據對象定義
record_name table_name%rowtype
record_name view_name%rowtype
reocrd_name cursor_name%rowtype
4、記錄的使用
1.使用記錄及記錄成員
undefine no
DECLARE
TYPE emp_record_type IS RECORD
(
name emp.ename%TYPE,
salary emp.sal%TYPE,
dno emp.deptno%TYPE
);
emp_record emp_record_type;
BEGIN
SELECT ename, sal, deptno INTO emp_record --[select ename,sal into emp_record.name,emp_record.salary]
FROM emp WHERE empno = &no;
dbms_output.put_line(emp_record.name); --輸出時僅僅輸出記錄變量的一個成員emp_record.name
END;
2.使用PL/SQL記錄(記錄成員)變量
DECLARE
dept_record dept%ROWTYPE;
BEGIN
dept_record.deptno := 50;
dept_record.dname := 'ADMINISTRATOR';
dept_record.loc := 'BEIJING';
INSERT INTO dept VALUES dept_record;
END;
3.記錄使用的幾個問題
a.記錄成員非空時必須在定義時給初值
DECLARE
TYPE ex_type IS RECORD
(col1 NUMBER(3),
col2 VARCHAR2(5) NOT NULL); --編譯不經過
ex_record ex_type;
BEGIN
ex_record.col1:=15;
ex_record.col1:=TO_CHAR(ex_record.col1);
ex_record.col2:='John';
DBMS_OUTPUT.PUT_LINE('ex_record.col1 is '||ex_record.col1);
DBMS_OUTPUT.PUT_LINE('ex_record.col2 is '||ex_record.col2);
END;
DECLARE
TYPE ex_type IS RECORD(
col1 NUMBER(3),
col2 VARCHAR2(5) NOT NULL := 'John');
ex_record ex_type;
BEGIN
ex_record.col1 := 15;
ex_record.col1 := TO_CHAR(ex_record.col1);
ex_record.col2:='TOM';--能夠賦新值
DBMS_OUTPUT.PUT_LINE('ex_record.col1 is ' || ex_record.col1);
DBMS_OUTPUT.PUT_LINE('ex_record.col2 is ' || ex_record.col2);
END;
b.來自不一樣的記錄類型的記錄變量之間不能相互賦值
c.同一個記錄的記錄變量之間能夠相互賦值
d.基於表,遊標,自定義記錄的使用
DECLARE
CURSOR dept_cur IS
SELECT * FROM dept WHERE deptno = 30;
TYPE dept_type IS RECORD(
deptno NUMBER(2),
dname VARCHAR2(14),
loc VARCHAR2(13));
dept_rec1 dept%ROWTYPE; --聲明基於表dept的記錄變量
dept_rec2 dept_cur%ROWTYPE; --聲明基於遊標dept_cur的記錄變量
dept_rec3 dept_type; --聲明基於自定義dept_type的記錄變量
BEGIN
SELECT * INTO dept_rec1 FROM dept WHERE deptno = 30;
OPEN dept_cur;
LOOP
FETCH dept_cur
INTO dept_rec2;
EXIT WHEN dept_cur%NOTFOUND;
END LOOP;
dept_rec1 := dept_rec2;
dept_rec3 := dept_rec2;
DBMS_OUTPUT.PUT_LINE(dept_rec1.deptno || ' ' || dept_rec1.dname);
DBMS_OUTPUT.PUT_LINE(dept_rec2.deptno || ' ' || dept_rec2.dname);
DBMS_OUTPUT.PUT_LINE(dept_rec3.deptno || ' ' || dept_rec3.dname);
END;
數據結構