SELECT [DISTICT|ALL]{*|column[,column,...]} INTO (variable[,variable,...] |record) FROM {table|(sub-query)}[alias] WHERE............ |
v_empno SCOTT.EMP.EMPNO%TYPE; v_salary EMP.SALARY%TYPE; |
DELCARE V_A NUMBER(5):=10; V_B V_A%TYPE:=15; V_C V_A%TYPE; BEGIN DBMS_OUTPUT.PUT_LINE (V_A=||V_A||V_B=||V_B||V_C=||V_C); END SQL>/ V_A=10 V_B=15 V_C= PL/SQL procedure suclearcase/" target="_blank" >ccessfully completed. SQL> |
CREATE OR REPLACE PROCEDURE FIRE_EMPLOYEE (pempno in number) AS v_ename EMP.ENAME%TYPE; BEGIN SELECT ename INTO v_ename FROM emp WHERE empno=p_empno; INSERT INTO FORMER_EMP(EMPNO,ENAME) VALUES (p_empno,v_ename); DELETE FROM emp WHERE empno=p_empno; UPDATE former_emp SET date_deleted=SYSDATE WHERE empno=p_empno; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE(Employee Number Not Found!); END |
隐式游标 | 显式游标 |
PL/SQL维护,当执行查询时自动打开和关闭 | 在程序中显式定义、打开、关闭,游标有一个名字。 |
游标属性前缀是SQL | 游标属性的前缀是游标名 |
属性%ISOPEN总是为FALSE | %ISOPEN根据游标的状态确定值 |
SELECT语句带有INTO子串,只有一行数据被处理 | 可以处理多行数据,在程序中设置循环,取出每一行数据。 |
使用游标
这里要做一个声明,我们所说的游标通常是指显式游标,因此从现在起没有特别指明的情况,我们所说的游标都是指显式游标。要在程序中使用游标,必须首先声明游标。
声明游标
语法:
CURSOR cursor_name IS select_statement; |
DELCARE CURSOR C_EMP IS SELECT empno,ename,salary FROM emp WHERE salary>2000 ORDER BY ename; ........ BEGIN |
OPEN cursor_name |
OPEN C_EMP; |
CLOSE cursor_name |
CLOSE C_EMP; |
FETCH cursor_name INTO variable[,variable,...] |
SET SERVERIUTPUT ON DECLARE v_ename EMP.ENAME%TYPE; v_salary EMP.SALARY%TYPE; CURSOR c_emp IS SELECT ename,salary FROM emp; BEGIN OPEN c_emp; FETCH c_emp INTO v_ename,v_salary; DBMS_OUTPUT.PUT_LINE(Salary of Employee|| v_ename ||is|| v_salary); FETCH c_emp INTO v_ename,v_salary; DBMS_OUTPUT.PUT_LINE(Salary of Employee|| v_ename ||is|| v_salary); FETCH c_emp INTO v_ename,v_salary; DBMS_OUTPUT.PUT_LINE(Salary of Employee|| v_ename ||is|| v_salary); CLOSE c_emp; END |
SET SERVERIUTPUT ON DECLARE v_ename EMP.ENAME%TYPE; v_salary EMP.SALARY%TYPE; CURSOR c_emp IS SELECT ename,salary FROM emp; BEGIN OPEN c_emp; LOOP FETCH c_emp INTO v_ename,v_salary; EXIT WHEN c_emp%NOTFOUND; DBMS_OUTPUT.PUT_LINE(Salary of Employee|| v_ename ||is|| v_salary); END |
SET SERVERIUTPUT ON DECLARE R_emp EMP%ROWTYPE; CURSOR c_emp IS SELECT * FROM emp; BEGIN OPEN c_emp; LOOP FETCH c_emp INTO r_emp; EXIT WHEN c_emp%NOTFOUND; DBMS_OUT.PUT.PUT_LINE(Salary of Employee||r_emp.ename||is|| r_emp.salary); END LOOP; CLOSE c_emp; END; |
SET SERVERIUTPUT ON DECLARE CURSOR c_emp IS SELECT ename,salary FROM emp; R_emp c_emp%ROWTYPE; BEGIN OPEN c_emp; LOOP FETCH c_emp INTO r_emp; EXIT WHEN c_emp%NOTFOUND; DBMS_OUT.PUT.PUT_LINE(Salary of Employee||r_emp.ename||is|| r_emp.salary); END LOOP; CLOSE c_emp; END; |
CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement; |
Parameter_name [IN] data_type[{:=|DEFAULT} value] |
OPEN cursor_name[value[,value]....]; |
DECALRE CURSOR c_dept IS SELECT * FROM dept ORDER BY deptno; CURSOR c_emp (p_dept VARACHAR2) IS SELECT ename,salary FROM emp WHERE deptno=p_dept ORDER BY ename r_dept DEPT%ROWTYPE; v_ename EMP.ENAME%TYPE; v_salary EMP.SALARY%TYPE; v_tot_salary EMP.SALARY%TYPE; BEGIN OPEN c_dept; LOOP FETCH c_dept INTO r_dept; EXIT WHEN c_dept%NOTFOUND; DBMS_OUTPUT.PUT_LINE(Department:|| r_dept.deptno||-||r_dept.dname); v_tot_salary:=0; OPEN c_emp(r_dept.deptno); LOOP FETCH c_emp INTO v_ename,v_salary; EXIT WHEN c_emp%NOTFOUND; DBMS_OUTPUT.PUT_LINE(Name:|| v_ename|| salary:||v_salary); v_tot_salary:=v_tot_salary+v_salary; END LOOP; CLOSE c_emp; DBMS_OUTPUT.PUT_LINE(Toltal Salary for dept:|| v_tot_salary); END LOOP; CLOSE c_dept; END; |
FOR record_name IN (corsor_name[(parameter[,parameter]...)] | (query_difinition) LOOP statements END LOOP; |
DECALRE CURSOR c_dept IS SELECT deptno,dname FROM dept ORDER BY deptno; CURSOR c_emp (p_dept VARACHAR2) IS SELECT ename,salary FROM emp WHERE deptno=p_dept ORDER BY ename v_tot_salary EMP.SALARY%TYPE; BEGIN FOR r_dept IN c_dept LOOP DBMS_OUTPUT.PUT_LINE(Department:|| r_dept.deptno||-||r_dept.dname); v_tot_salary:=0; FOR r_emp IN c_emp(r_dept.deptno) LOOP DBMS_OUTPUT.PUT_LINE(Name:|| v_ename|| salary:||v_salary); v_tot_salary:=v_tot_salary+v_salary; END LOOP; DBMS_OUTPUT.PUT_LINE(Toltal Salary for dept:|| v_tot_salary); END LOOP; END; |
DECALRE v_tot_salary EMP.SALARY%TYPE; BEGIN FOR r_dept IN (SELECT deptno,dname FROM dept ORDER BY deptno) LOOP DBMS_OUTPUT.PUT_LINE(Department:|| r_dept.deptno||-||r_dept.dname); v_tot_salary:=0; FOR r_emp IN (SELECT ename,salary FROM emp WHERE deptno=p_dept ORDER BY ename) LOOP DBMS_OUTPUT.PUT_LINE(Name:|| v_ename|| salary:||v_salary); v_tot_salary:=v_tot_salary+v_salary; END LOOP; DBMS_OUTPUT.PUT_LINE(Toltal Salary for dept:|| v_tot_salary); END LOOP; END; |
CURSOR C1 IS SELECT * FROM emp WHERE deptno NOT IN (SELECT deptno FROM dept WHERE dname!=ACCOUNTING); |
FOR UPDATE [OF [schema.]table.column[,[schema.]table.column].. [nowait] |
WHERE{CURRENT OF cursor_name|search_condition} |
DELCARE CURSOR c1 IS SELECT empno,salary FROM emp WHERE comm IS NULL FOR UPDATE OF comm; v_comm NUMBER(10,2); BEGIN FOR r1 IN c1 LOOP IF r1.salary<500 THEN v_comm:=r1.salary*0.25; ELSEIF r1.salary<1000 THEN v_comm:=r1.salary*0.20; ELSEIF r1.salary<3000 THEN v_comm:=r1.salary*0.15; ELSE v_comm:=r1.salary*0.12; END IF; UPDATE emp; SET comm=v_comm WHERE CURRENT OF c1l; END LOOP; END |