游标的概念:
Sql代码
- 隐式游标的属性 返回值类型 意 义
- SQL%ROWCOUNT 整型 代表DML语句成功执行的数据行数
- SQL%FOUND 布尔型 值为TRUE代表插入、删除、更新或单行查询操作成功
- SQL%NOTFOUND 布尔型 与SQL%FOUND属性返回值相反
- SQL%ISOPEN 布尔型 DML执行过程中为真,结束后为假
Sql代码
- SET SERVEROUTPUT ON
- BEGIN
- UPDATE emp SET sal=sal+100 WHERE empno=1234;
- IF SQL%FOUND THEN
- DBMS_OUTPUT.PUT_LINE(‘成功修改雇员工资!’);
- COMMIT;
- ELSE
- DBMS_OUTPUT.PUT_LINE(‘修改雇员工资失败!’);
- END IF;
- END;
Sql代码
- 修改雇员工资失败!
- PL/SQL 过程已成功完成。
Sql代码
- 成功修改雇员工资!
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- v_ename VARCHAR2(10);
- v_job VARCHAR2(10);
- CURSOR emp_cursor IS
- SELECT ename,job FROM emp WHERE empno=7788;
- BEGIN
- OPEN emp_cursor;
- FETCH emp_cursor INTO v_ename,v_job;
- DBMS_OUTPUT.PUT_LINE(v_ename||‘,’||v_job);
- CLOSE emp_cursor;
- END;
Sql代码
- SCOTT,ANALYST
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- CURSOR emp_cursor IS SELECT ename,job,sal FROM emp WHERE empno=7788;
- emp_record emp_cursor%ROWTYPE;
- BEGIN
- OPEN emp_cursor;
- FETCH emp_cursor INTO emp_record;
- DBMS_OUTPUT.PUT_LINE(emp_record.ename||‘,’|| emp_record.job||’,’|| emp_record.sal);
- CLOSE emp_cursor;
- END;
Sql代码
- SCOTT,ANALYST,3000
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- V_ename VARCHAR2(10);
- V_sal NUMBER(5);
- CURSOR emp_cursor IS SELECT ename,sal FROM emp ORDER BY sal DESC;
- BEGIN
- OPEN emp_cursor;
- FOR I IN 1..3 LOOP
- FETCH emp_cursor INTO v_ename,v_sal;
- DBMS_OUTPUT.PUT_LINE(v_ename||‘,’||v_sal);
- END LOOP;
- CLOSE emp_cursor;
- END;
Sql代码
- KING,5000
- SCOTT,3000
- FORD,3000
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- CURSOR emp_cursor IS
- SELECT empno, ename FROM emp;
- BEGIN
- FOR Emp_record IN emp_cursor LOOP
- DBMS_OUTPUT.PUT_LINE(Emp_record.empno|| Emp_record.ename);
- END LOOP;
- END;
Sql代码
- 7369SMITH
- 7499ALLEN
- 7521WARD
- 7566JONES
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- BEGIN
- FOR re IN (SELECT ename FROM EMP) LOOP
- DBMS_OUTPUT.PUT_LINE(re.ename)
- END LOOP;
- END;
Sql代码
- SMITH
- ALLEN
- WARD
- JONES
Sql代码
- 游标的属性 返回值类型 意 义
- %ROWCOUNT 整型 获得FETCH语句返回的数据行数
- %FOUND 布尔型 最近的FETCH语句返回一行数据则为真,否则为假
- %NOTFOUND 布尔型 与%FOUND属性返回值相反
- %ISOPEN 布尔型 游标已经打开时值为真,否则为假
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- V_ename VARCHAR2(10);
- CURSOR emp_cursor IS
- SELECT ename FROM emp;
- BEGIN
- OPEN emp_cursor;
- IF emp_cursor%ISOPEN THEN
- LOOP
- FETCH emp_cursor INTO v_ename;
- EXIT WHEN emp_cursor%NOTFOUND;
- DBMS_OUTPUT.PUT_LINE(to_char(emp_cursor%ROWCOUNT)||‘-‘||v_ename);
- END LOOP;
- ELSE
- DBMS_OUTPUT.PUT_LINE(‘用户信息:游标没有打开!’);
- END IF;
- CLOSE emp_cursor;
- END;
Sql代码
- 1-SMITH
- 2-ALLEN
- 3-WARD
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- V_empno NUMBER(5);
- V_ename VARCHAR2(10);
- CURSOR emp_cursor(p_deptno NUMBER, p_job VARCHAR2) IS
- SELECT empno, ename FROM emp
- WHERE deptno = p_deptno AND job = p_job;
- BEGIN
- OPEN emp_cursor(10, ‘CLERK’);
- LOOP
- FETCH emp_cursor INTO v_empno,v_ename;
- EXIT WHEN emp_cursor%NOTFOUND;
- DBMS_OUTPUT.PUT_LINE(v_empno||‘,’||v_ename);
- END LOOP;
- END;
Sql代码
- 7934,MILLER
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- v_empno NUMBER(5);
- v_ename VARCHAR2(10);
- v_deptno NUMBER(5);
- v_job VARCHAR2(10);
- CURSOR emp_cursor IS
- SELECT empno, ename FROM emp
- WHERE deptno = v_deptno AND job = v_job;
- BEGIN
- v_deptno:=10;
- v_job:=‘CLERK’;
- OPEN emp_cursor;
- LOOP
- FETCH emp_cursor INTO v_empno,v_ename;
- EXIT WHEN emp_cursor%NOTFOUND;
- DBMS_OUTPUT.PUT_LINE(v_empno||‘,’||v_ename);
- END LOOP;
- END;
Sql代码
- 7934,MILLER
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- str varchar2(100);
- v_ename varchar2(10);
- begin
- str:=‘select ename from scott.emp where empno=7788’;
- execute immediate str into v_ename;
- dbms_output.put_line(v_ename);
- END;
Sql代码
- SCOTT
- PL/SQL 过程已成功完成。
Sql代码
- declare
- type cur_type is ref cursor;
- cur cur_type;
- rec scott.emp%rowtype;
- str varchar2(50);
- letter char:= ‘A’;
- begin
- loop
- str:= ‘select ename from emp where ename like ”%’||letter||’%”’;
- open cur for str;
- dbms_output.put_line(‘包含字母’||letter||’的名字:’);
- loop
- fetch cur into rec.ename;
- exit when cur%notfound;
- dbms_output.put_line(rec.ename);
- end loop;
- exit when letter=‘Z’;
- letter:=chr(ascii(letter)+1);
- end loop;
- end;
Sql代码
- 包含字母A的名字:
- ALLEN
- WARD
- MARTIN
- BLAKE
- CLARK
- ADAMS
- JAMES
- 包含字母B的名字:
- BLAKE
- 包含字母C的名字:
- CLARK
- SCOTT
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- v_name VARCHAR2(10);
- BEGIN
- SELECT ename
- INTO v_name
- FROM emp
- WHERE empno = 1234;
- DBMS_OUTPUT.PUT_LINE(‘该雇员名字为:’|| v_name);
- EXCEPTION
- WHEN NO_DATA_FOUND THEN
- DBMS_OUTPUT.PUT_LINE(‘编号错误,没有找到相应雇员!’);
- WHEN OTHERS THEN
- DBMS_OUTPUT.PUT_LINE(‘发生其他错误!’);
- END;
Sql代码
- 编号错误,没有找到相应雇员!
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- v_temp NUMBER(5):=1;
- BEGIN
- v_temp:=v_temp/0;
- EXCEPTION
- WHEN OTHERS THEN
- DBMS_OUTPUT.PUT_LINE(‘发生系统错误!’);
- DBMS_OUTPUT.PUT_LINE(‘错误代码:’|| SQLCODE( ));
- DBMS_OUTPUT.PUT_LINE(‘错误信息:’ ||SQLERRM( ));
- END;
Sql代码
- 发生系统错误!
- 错误代码:?1476
- 错误信息:ORA-01476: 除数为 0
- PL/SQL 过程已成功完成。
Sql代码
- 错 误 名 称 错误代码 错 误 含 义
- CURSOR_ALREADY_OPEN ORA_06511 试图打开已经打开的游标
- INVALID_CURSOR ORA_01001 试图使用没有打开的游标
- DUP_VAL_ON_INDEX ORA_00001 保存重复值到惟一索引约束的列中
- ZERO_DIVIDE ORA_01476 发生除数为零的除法错误
- INVALID_NUMBER ORA_01722 试图对无效字符进行数值转换
- ROWTYPE_MISMATCH ORA_06504 主变量和游标的类型不兼容
- VALUE_ERROR ORA_06502 转换、截断或算术运算发生错误
- TOO_MANY_ROWS ORA_01422 SELECT…INTO…语句返回多于一行的数据
- NO_DATA_FOUND ORA_01403 SELECT…INTO…语句没有数据返回
- TIMEOUT_ON_RESOURCE ORA_00051 等待资源时发生超时错误
- TRANSACTION_BACKED_OUT ORA_00060 由于死锁,提交失败
- STORAGE_ERROR ORA_06500 发生内存错误
- PROGRAM_ERROR ORA_06501 发生PL/SQL内部错误
- NOT_LOGGED_ON ORA_01012 试图操作未连接的数据库
- LOGIN_DENIED ORA_01017 在连接时提供了无效用户名或口令
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- V_ENAME VARCHAR2(10);
- NULL_INSERT_ERROR EXCEPTION;
- PRAGMA EXCEPTION_INIT(NULL_INSERT_ERROR,-1400);
- BEGIN
- INSERT INTO EMP(EMPNO) VALUES(NULL);
- EXCEPTION
- WHEN NULL_INSERT_ERROR THEN
- DBMS_OUTPUT.PUT_LINE(‘无法插入NULL值!’);
- WHEN OTHERS THEN
- DBMS_OUTPUT.PUT_LINE(‘发生其他系统错误!’);
- END;
Sql代码
- 无法插入NULL值!
- PL/SQL 过程已成功完成。
Java代码
- SET SERVEROUTPUT ON
- DECLARE
- new_no NUMBER(10);
- new_excp1 EXCEPTION;
- new_excp2 EXCEPTION;
- BEGIN
- new_no:=6789;
- INSERT INTO emp(empno,ename)
- VALUES(new_no, ‘小郑’);
- IF new_no<7000 THEN
- RAISE new_excp1;
- END IF;
- IF new_no>8000 THEN
- RAISE new_excp2;
- END IF;
- COMMIT;
- EXCEPTION
- WHEN new_excp1 THEN
- ROLLBACK;
- DBMS_OUTPUT.PUT_LINE(‘雇员编号小于7000的下限!’);
- WHEN new_excp2 THEN
- ROLLBACK;
- DBMS_OUTPUT.PUT_LINE(‘雇员编号超过8000的上限!’);
- END;
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- New_no NUMBER(10);
- BEGIN
- New_no:=6789;
- INSERT INTO emp(empno,ename)
- VALUES(new_no, ‘JAMES’);
- IF new_no<7000 THEN
- ROLLBACK;
- RAISE_APPLICATION_ERROR(-20001, ‘编号小于7000的下限!’);
- END IF;
- IF new_no>8000 THEN
- ROLLBACK;
- RAISE_APPLICATION_ERROR (-20002, ‘编号大于8000的下限!’);
- END IF;
- END;
Sql代码
- DECLARE
- *
- ERROR 位于第 1 行:
- ORA-20001: 编号小于7000的下限!
- ORA-06512: 在line 9
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- v_empno NUMBER(5):=7788;
- emp_rec emp%ROWTYPE;
- BEGIN
- SELECT * INTO emp_rec FROM emp WHERE empno=v_empno;
- DELETE FROM emp WHERE empno=v_empno;
- INSERT INTO emp1 VALUES emp_rec;
- IF SQL%FOUND THEN
- COMMIT;
- DBMS_OUTPUT.PUT_LINE(‘雇员复制成功!’);
- ELSE
- ROLLBACK;
- DBMS_OUTPUT.PUT_LINE(‘雇员复制失败!’);
- END IF;
- END;
Sql代码
- EMPNO ENAME JOB
- ————- ————– —————-
- 7788 SCOTT ANALYST
Sql代码
- SET SERVEROUTPUT ON
- BEGIN
- FOR re IN (SELECT ename,sal FROM EMP) LOOP
- DBMS_OUTPUT.PUT_LINE(rpad(re.ename,12,‘ ‘)||rpad(‘*’,re.sal/100,’*’));
- END LOOP;
- END;
Sql代码
- SMITH
- ALLEN
- WARD *
- JONES
- MARTIN *
- BLAKE *
- CLARK *
- SCOTT
- KING
- TURNER *
- ADAMS *
- JAMES
- FORD
- MILLER *
- 执行结果为:
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- v_count number:=0;
- CURSOR dept_cursor IS SELECT * FROM dept;
- BEGIN
- DBMS_OUTPUT.PUT_LINE(‘部门列表’);
- DBMS_OUTPUT.PUT_LINE(‘———————————‘);
- FOR Dept_record IN dept_cursor LOOP
- DBMS_OUTPUT.PUT_LINE(‘部门编号:’|| Dept_record.deptno);
- DBMS_OUTPUT.PUT_LINE(‘部门名称:’|| Dept_record.dname);
- DBMS_OUTPUT.PUT_LINE(‘所在城市:’|| Dept_record.loc);
- DBMS_OUTPUT.PUT_LINE(‘———————————‘);
- v_count:= v_count+1;
- END LOOP;
- DBMS_OUTPUT.PUT_LINE(‘共有’||to_char(v_count)||’个部门!’);
- END;
Sql代码
- 部门列表
- ————————————
- 部门编号:10
- 部门名称:ACCOUNTING
- 所在城市:NEW YORK
- ————————————
- 部门编号:20
- 部门名称:RESEARCH
- 所在城市:DALLAS
- …
- 共有4个部门!
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- v_deptno number(8);
- v_count number(3);
- v_sumsal number(6);
- v_dname varchar2(15);
- v_manager varchar2(15);
- CURSOR list_cursor IS
- SELECT deptno,count(*),sum(sal) FROM emp group by deptno;
- BEGIN
- OPEN list_cursor;
- DBMS_OUTPUT.PUT_LINE(‘———– 部 门 统 计 表 ———–‘);
- DBMS_OUTPUT.PUT_LINE(‘部门名称 总人数 总工资 部门经理’);
- FETCH list_cursor INTO v_deptno,v_count,v_sumsal;
- WHILE list_cursor%found LOOP
- SELECT dname INTO v_dname FROM dept
- WHERE deptno=v_deptno;
- SELECT ename INTO v_manager FROM emp
- WHERE deptno=v_deptno and job=‘MANAGER’;
- DBMS_OUTPUT.PUT_LINE(rpad(v_dname,13)||rpad(to_char(v_count),8)
- ||rpad(to_char(v_sumsal),9)||v_manager);
- FETCH list_cursor INTO v_deptno,v_count,v_sumsal;
- END LOOP;
- DBMS_OUTPUT.PUT_LINE(‘————————————–‘);
- CLOSE list_cursor;
- END;
Sql代码
- ——————– 部 门 统 计 表 —————–
- 部门名称 总人数 总工资 部门经理
- ACCOUNTING 3 8750 CLARK
- RESEARCH 5 10875 JONES
- SALES 6 9400 BLAKE
- ————————————————————-
- PL/SQL 过程已成功完成。
Sql代码
- SET SERVEROUTPUT ON
- DECLARE
- V_NAME CHAR(10);
- V_EMPNO NUMBER(5);
- V_SAL NUMBER(8);
- V_SAL1 NUMBER(8);
- V_TOTAL NUMBER(8) := 800; –增加工资的总额
- V_NUM NUMBER(5):=0; –增加工资的人数
- CURSOR emp_cursor IS
- SELECT EMPNO,ENAME,SAL FROM EMP ORDER BY SAL ASC;
- BEGIN
- OPEN emp_cursor;
- DBMS_OUTPUT.PUT_LINE(‘姓名 原工资 新工资’);
- DBMS_OUTPUT.PUT_LINE(‘—————————‘);
- LOOP
- FETCH emp_cursor INTO V_EMPNO,V_NAME,V_SAL;
- EXIT WHEN emp_cursor%NOTFOUND;
- V_SAL1:= V_SAL*0.1;
- IF V_TOTAL>V_SAL1 THEN
- V_TOTAL := V_TOTAL – V_SAL1;
- V_NUM:=V_NUM+1;
- DBMS_OUTPUT.PUT_LINE(V_NAME||TO_CHAR(V_SAL,‘99999’)||
- TO_CHAR(V_SAL+V_SAL1,‘99999’));
- UPDATE EMP SET SAL=SAL+V_SAL1
- WHERE EMPNO=V_EMPNO;
- ELSE
- DBMS_OUTPUT.PUT_LINE(V_NAME||TO_CHAR(V_SAL,‘99999’)||TO_CHAR(V_SAL,’99999′));
- END IF;
- END LOOP;
- DBMS_OUTPUT.PUT_LINE(‘—————————‘);
- DBMS_OUTPUT.PUT_LINE(‘增加工资人数:’||V_NUM||’ 剩余工资:’||V_TOTAL);
- CLOSE emp_cursor;
- COMMIT;
- END;
Sql代码
- 姓名 原工资 新工资
- ———————————————
- SMITH 1289 1418
- JAMES 1531 1684
- MARTIN 1664 1830
- MILLER 1730 1903
- ALLEN 1760 1936
- ADAMS 1771 1771
- TURNER 1815 1815
- WARD 1830 1830
- BLAKE 2850 2850
- CLARK 2850 2850
- JONES 2975 2975
- FORD 3000 3000
- KING 5000 5000
- ———————————————–
- 增加工资人数:5 剩余工资:3
- PL/SQL 过程已成功完成。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/200103.html原文链接:https://javaforall.net
