`

精通Oracle10编程SQL(10)处理例外

阅读更多
/*
 *处理例外
 */
--例外简介
--处理例外-传递例外
declare
   v_ename emp.ename%TYPE;
begin
   SELECT ename INTO v_ename FROM emp
      where empno=&no;
   dbms_output.put_line('雇员名:'||v_ename);
exception
   when too_many_rows then
      dbms_output.put_line('查询只能返回单行');
end;

select * from emp;

--捕捉并处理例外
DECLARE
  v_ename emp.ename%TYPE;
BEGIN
  select ename into v_ename from emp where empno=&no;
  dbms_output.put_line('雇员名:'||v_ename);
EXCEPTION
  when NO_DATA_FOUND THEN
     dbms_output.put_line('雇员号不正确,请核实雇员号!');
END;

--处理预定义例外
--常用预定义例外
--ACCESS_INTO_NULL
declare
  empt emp_type;
begin
  empt.name:='SCOTT';
exception
  when ACCESS_INTO_NULL THEN
     dbms_output.put_line('首先初始化对象emp');
end;

--CASE_NOT_FOUND
DECLARE
   v_sal emp.sal%TYPE;
BEGIN
   SELECT sal into v_sal from emp where empno=&no;
   case
      when v_sal<100 then
         update emp set sal=sal+100 where empno=&no;
      when v_sal<200 then
         update emp set sal=sal+150 where empno=&no;
      when v_sal<300 then
         update emp set sal=sal+200 where empno=&no;
   end case;
EXCEPTION
   when case_not_found then
      dbms_output.put_line('在CASE语句中缺少与'||v_sal||'相关的条件');
END;

select * from emp;

--COLLECTION_IS_NULL
DECLARE
   TYPE ename_table_type is table of emp.ename%TYPE;
   ename_table ename_table_type;
BEGIN
   select ename into ename_table(2) from emp
     where empno=&no;
   dbms_output.put_line('雇员名:'||ename_table(2));
EXCEPTION
   WHEN COLLECTION_IS_NULL then
      dbms_output.put_line('必须使用构造方法初始化集合元素');
END;

--CURSOR_ALREADY_0PEN
declare
   CURSOR emp_cursor is select ename,sal from emp;
begin
   open emp_cursor;
   for emp_record in emp_cursor loop
      dbms_output.put_line(emp_record.ename);
   end loop;
exception
   when cursor_already_open then
       dbms_output.put_line('游标已经打开');
end;

--给dept表加主键
alter table dept add primary key(deptno);
select * from dept;

--DUP_VAL_ON_INDEX
BEGIN
   UPDATE dept set deptno=&new_no where deptno=&old_no;
EXCEPTION
   when DUP_VAL_ON_INDEX THEN
      dbms_output.put_line('在deptno列上不能出现重复值');
END;

--INVALID_CURSOR
DECLARE
   cursor emp_cursor is select ename,sal from emp;
   emp_record emp_cursor%ROWTYPE;
BEGIN
   --open emp_cursor;
   FETCH emp_cursor into emp_record;
   close emp_cursor;
EXCEPTION
   WHEN invalid_cursor then
      dbms_output.put_line('请检查游标是否已经打开');
END;

--INVALID_NUMBER
begin
   update emp set sal=sal+'1oo';
exception
   when invalid_number then
      dbms_output.put_line('输入的数字值不正确');
end;

--NO_DATA_FOUND
DECLARE
  v_sal emp.sal%TYPE;
BEGIN
  select sal into v_sal from emp
    where lower(ename)=lower('&name');
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    dbms_output.put_line('不存在该雇员');
END;

select * from emp;

--TOO_MANY_ROWS
DECLARE
   v_ename emp.ename%TYPE;
BEGIN
   select ename into v_ename from emp where sal=&sal;
EXCEPTION
   WHEN TOO_MANY_ROWS THEN
     DBMS_OUTPUT.put_line('返回多行');
END;

--ZERO_DIVIDE
DECLARE
  num1 int:=100;
  num2 int:=0;
  num3 number(6,2);
BEGIN
  num3:=num1/num2;
EXCEPTION
  WHEN ZERO_DIVIDE THEN
     dbms_output.put_line('分母不能为0');
END;

--SUBSCRIPT_BEYOND_COUNT
declare
   type emp_array_type is varray(20) of varchar2(10);
   emp_array emp_array_type;
begin
   emp_array:=emp_array_type('SCOTT','MARY');
   dbms_output.put_line(emp_array(3));
exception
   when subscript_beyond_count then
      dbms_output.put_line('超出下标范围');
end;

--SUBSCRIPT_OUTSIDE_LIMIT
DECLARE
   TYPE emp_array_type is varray(20) of varchar2(10);
   emp_array emp_array_type;
BEGIN
   emp_array:=emp_array_type('SCOTT','MARY');
   dbms_output.put_line(emp_array(-1));
EXCEPTION
   WHEN SUBSCRIPT_OUTSIDE_LIMIT THEN
      dbms_output.put_line('嵌套表和VARRAY下标不能为负');
END;

--VALUE_ERROR
DECLARE
   v_ename varchar2(5);
BEGIN
   SELECT ename into v_ename from emp where empno=&no;
   dbms_output.put_line(v_ename);
EXCEPTION
   when VALUE_ERROR THEN
      dbms_output.put_line('变量尺寸不足');
END;

--处理非预定义例外

--建立主外键约束关系
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept FOREIGN KEY (deptno) REFERENCES dept(deptno);

--因为在DEPT表和EMP表之间具有主外键关系,所以当修改雇员的部门号时,部门号必须在DEPT表中存在。
--如果该部门号在表中不存在,则会隐含触发ORA-02291对应的例外e_integrity,并显示合理的输出信息。
declare
  e_integrity EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_integrity,-2291);
begin
  update emp set deptno=&dno where empno=&eno;
exception
  when e_integrity then
    dbms_output.put_line('该部门不存在');
end;

--处理自定义例外
declare
  e_integrity EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_integrity,-2291);
  e_no_employee EXCEPTION;
begin
  update emp set deptno=&dno where empno=&eno;
  IF SQL%NOTFOUND THEN
     RAISE e_no_employee;
  END IF;
exception
  when e_integrity then
    dbms_output.put_line('该部门不存在');
  when e_no_employee then
    dbms_output.put_line('该雇员不存在');
end;

--使用例外函数
--SQLCODE和SQLERRM
DECLARE
   v_ename emp.ename%TYPE;
BEGIN
   SELECT ename into v_ename from emp
     where sal=&v_sal;
   dbms_output.put_line('雇员名:'||v_ename);
EXCEPTION
   when no_data_found then
      dbms_output.put_line('不存在工资为'||&v_sal||'的雇员');
   when others then
      dbms_output.put_line('错误号:'||SQLCODE);
      dbms_output.put_line(SQLERRM);
END;

select * from emp;

--RAISE_APPLICATION_ERROR
CREATE OR REPLACE PROCEDURE raise_comm
   (eno NUMBER,commission NUMBER)
IS
   v_comm emp.comm%TYPE;
BEGIN
   select comm into v_comm from emp where empno=eno;
   if v_comm is null then
      raise_application_error(-20001,'该雇员无补助');
   end if;
EXCEPTION
   when NO_DATA_FOUND THEN
      dbms_output.put_line('该雇员不存在');
END;

begin
  raise_comm(8,100);
end;

select * from emp for update;


--PL/SQL编译警告
--PL/SQL警告分类
--分成三类警告消息,PL/SQL警告分类如下
--SEVERE:该种警告用于检查可能出现的不可预料结果或错误结果,例如参数的别名问题
--PERFORMANCE:该类警告用于检查可能引起的性能问题,例如在执行INSERT操作时为NUMBER列提供了VARCHAR2类型的数据
--INFORMATIONAL:该类警告用于检查子程序中的死代码
--ALL:该关键字用于检查所有警告(SEVERE,PERFORMACE,INFORMATIONAL)

--检测死代码
CREATE OR REPLACE PROCEDURE dead_code AS
  x number:=10;
BEGIN
  if x=10 then
    x:=20;
  else
    x:=100; --死代码(永远不会执行)
  end if;
END dead_code;

--SQL*PLUS上执行如下命令行
alter session set PLSQL_WARNINGS='ENABLE:INFORMATIONAL';
alter procedure dead_code compile;
show errors;

--检测引起性能问题的代码
CREATE OR REPLACE PROCEDURE update_sal
   (name varchar2,salary varchar2)
is
begin
   update emp set sal=salary where ename=name;
end;

--SQL*PLUS上执行如下命令行
ALTER SESSION SET PLSQL_WARNINGS='ENABLE:PERFORMANCE';
ALTER PROCEDURE update_sal compile;
show errors;

 

分享到:
评论

相关推荐

    精通Oracle10编程SQL(1-3)PLSQL基础

    "精通Oracle10编程SQL(9)使用游标.sql"讲解了游标的概念和应用,游标是数据库编程中的重要工具,用于逐行处理查询结果,尤其在循环处理或动态操作数据时非常有用。 "精通Oracle10编程SQL(11)开发子程序.sql"和"精通...

    精通 ORACLE SQL高级编程 学习笔记

    精通Oracle SQL【第2版】ORACLE SQL高级编程【第二版】学习笔记

    精通Oracle 10g SQL和PL SQL.zip

    本资源“精通Oracle 10g SQL和PL SQL.zip”提供了全面的学习指南,帮助用户从基础到高级进阶,掌握这两个重要组件的精髓。 SQL(Structured Query Language)是用于管理关系数据库的标准语言,它允许用户创建、查询...

    精通ORACLE 10G SQL和PLSQL

    精通ORACLE 10G SQL和PLSQL

    精通Oracle10编程.pdf

    精通Oracle10编程.pdf

    精通Oracle 10g SQL和PL SQL.pdf

    《精通Oracle 10g SQL和PL/SQL》是专门为Oracle应用开发人员所提供的SQL和PL/SQL编程指南。通过学习《精通Oracle 10g SQL和PL/SQL》,读者不仅可以掌握SQL和PL/SQL的基础知识,而且还可以掌握SQL高级特征(正则...

    《精通Oracle10编程》 PDF

    《精通Oracle10编程》是一本专为数据库管理员和开发者设计的专业书籍,旨在深入解析Oracle 10g数据库系统的各种核心技术和高级特性。Oracle 10g是Oracle公司推出的一个重要版本,它在性能、可扩展性和管理性方面都有...

    精通Oracle 10g SQL和PL/SQL

    sql是关系数据库的基本操作语言 它是应用程序与数据库进行交互操作的接口 pl/sql是oracle特有的编程语言 它不仅具有过程编程语言的基本特征 循环 条件分支等 而且还具有对象编程语言的高级特征 重载 继承等 ...

    精通ORACLE10GPLSQL编程

    精通ORACLE10GPLSQL编程 、

    精通Oracle PLSQL编程

    PL/SQL(Procedural Language/Structured Query Language)是Oracle数据库提供的一个过程化语言,它结合了SQL的查询功能和传统的过程式编程语言的控制结构,使得数据库管理和应用程序开发更加高效和灵活。...

    《精通Oracle PL/SQL》源码

    Oracle PL/SQL是一种强大的编程语言,它结合了SQL(结构化查询语言)的数据库操作能力和PL(过程化语言)的程序设计特性,是Oracle数据库系统中的核心组件之一。《精通Oracle PL/SQL》这本书深入探讨了这个语言的...

    精通Oracle10g SQL/PL编程.PDF

    《精通Oracle10g SQL/PL编程》是一本专为数据库开发者和管理员设计的专业书籍,旨在深入探讨Oracle10g数据库管理系统中的SQL和PL/SQL编程技术。这本书以通俗易懂的方式,为初学者提供了全面的学习路径,同时也为有...

    精通Oracle10编程

    精通 Oracle10 编程

    Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(一)

     本书是专门为oracle应用开发人员提供的sql和pl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法...

    精通oracle10编程 教程 +pl/sql pdf

    本教程的"精通Oracle10编程"部分,将深入讲解如何使用PL/SQL进行数据库交互,包括变量声明、流程控制、异常处理和游标等基本概念。 在PL/SQL编程中,了解SQL DML语句(INSERT、UPDATE、DELETE)是基础,它们用于...

Global site tag (gtag.js) - Google Analytics