【Oracle】第四章异常处理
第四章异常处理
PL/SQL 块是构成 PL/SQL 程序的基本单元
将逻辑上相关的声明和语句组合在一起
PL/SQL 分为三个部分,声明部分、可执行部分和异常处理部分
[DECLARE declarations] BEGIN executable statements [EXCEPTION handlers] END;
以下示例演示了如何使用PL/SQL 语句:
declare area integer; width integer; height integer; currentdate date; cnumber constant integer := 10; begin area :=10; height :=2; width := area/height; currentdate :=sysdate; DBMS_OUTPUT.put_line('宽 = '||width); DBMS_OUTPUT.put_line('高 ='||height); DBMS_OUTPUT.put_line('面积 ='||area); DBMS_OUTPUT.put_line('常量的值为:'||cnumber); DBMS_OUTPUT.put_line('当前时间为:'||currentdate); exception when zero_divide then DBMS_OUTPUT.put_line('除数不能为零'); end;
给变量赋值有两种形式:
使用赋值语句 :=
使用 SELECT INTO 语句
使用常量赋值:
cnumber constant integer := 10;
以下代码演示了使用常量和SELECT INTO 语句:
declare firstName varchar2(20); lastName varchar2(20); employeeid number; consNumber constant integer :=1000; begin select employee_id, first_name,last_name into employeeid, firstName,lastname from employees2 where employee_id =1; DBMS_OUTPUT.put_line('consNumber = '||consNumber); DBMS_OUTPUT.put_line('employeeid='||firstName); DBMS_OUTPUT.put_line('firstName='||firstName); DBMS_OUTPUT.put_line('lastName='||lastname); end;
CLOB数据类型的使用。
create table my_book_text( chapter_id number(3), chapter_descr varchar2(40), chapter_text clob);
添加数据到clob字段 chapter_text :
insert into my_book_text values(5,'第五章 PL/SQL 简介','PL/SQL 可用于创建存储过程,触发器和程序包等,用来处理业务规则,数据库时间或给SQL命令的执行添加程序逻辑。');
读取 CLOB 数据类型:
set serveroutput on declare clob_var clob; amount integer; offset integer; output_var varchar2(100); begin select chapter_content into clob_var from my_book_text where chapterid=1; amount :=20; offset :=5; DBMS_LOB.READ(clob_var,amount,offset,output_var); DBMS_OUTPUT.put_line(output_var); end; /
PL/SQL 支持的流程控制结构:
条件控制
IF 语句
CASE 语句
循环控制
LOOP 循环
WHILE 循环
FOR 循环
顺序控制
GOTO 语句
NULL 语句
以下代码演示了条件控制(IF-THEN-ELSE语句):
declare age number(8); begin age := &age; if age>20 and age<30 then dbms_output.put_line('年龄在20 和30 之间 '); elsif age < 20 then dbms_output.put_line('年龄小于20'); else dbms_output.put_line('年龄大于30'); end if; end; /
以下代码演示了从 employees2 表中检索employee_id 为 3 的记录 ,如果 salary 大于 15000 则减去 1000 ,否则salary 加 100
declare firstName varchar(20); lastName varchar2(20); salarytemp number(10); begin select first_name,last_name,salary into firstName,lastName,salarytemp from employees2 where employee_id=3; if salarytemp > 15000 then update employees2 set salary = salary-1000 where employee_id = 3; else update employees2 set salary = salary+100 where employee_id=3; end if; dbms_output.put_line('firstName ='||firstName); dbms_output.put_line('lastName='||lastName); dbms_output.put_line('salarytemp = '||salarytemp); end;
Case 语句:
以下代码演示了选择器。系统先计算选择器值。然后再依次选择 WHEN 子句。
set serveroutput on begin case '&grade' when 'A' then dbms_output.put_line('优异'); when 'B' then dbms_output.put_line('优秀'); when 'C' then dbms_output.put_line('良好'); when 'D' then dbms_output.put_line('一般'); when 'E' then dbms_output.put_line('较差'); else dbms_output.put_line('没有此成绩'); end case; end; /
Loop 循环:以下代码演示了loop的使用
declare x number; begin x :=0; loop x:=x+1; if x>=3 then exit; end if; dbms_output.put_line('循环体 x ='||x); end loop; dbms_output.put_line('循环体外 x ='||x); end; /
另外一种表现形式:
declare x number; begin x :=0; loop x:=x+1; exit when x>=3; dbms_output.put_line('循环体内 x ='||x); end loop; dbms_output.put_line('循环体外 x ='||x); end;
While循环:
declare x number ; begin x:=0; while x<=3 loop x:=x+1; dbms_output.put_line('循环内'||x); end loop; dbms_output.put_line('循环外'||x); end; /
以下代码演示了while 循环得使用。声明了销量的 monthly_value 和 daily_value,并将其初始化为0。While执行循环,直至每月销量的值大于等于4000
set serveroutput on declare monthly_value number :=0; daily_value number :=0; begin while monthly_value <= 4000 loop monthly_value := daily_value * 31; daily_value := daily_value +10; dbms_output.put_line('每日销量:' || daily_value); end loop; dbms_output.put_line('每月销量' || monthly_value); end; /
For循环语句:
begin for i in 1..5 loop dbms_output.put_line('循环 I 的值 = '||i); end loop; dbms_output.put_line('end loop'); end; / Reverse(递减) 的使用 begin for i in reverse 1..5 loop dbms_output.put_line('循环 I 的值 = '||i); end loop; dbms_output.put_line('end loop'); end; /
以下代码显示了25个偶数
set serveroutput on begin for eve_number in 1..25 loop dbms_output.put_line(eve_number*2); end loop; end; /
Oracle 中异常的处理:
预定义异常:
返回多行异常:
declare firstname varchar2(20); begin select first_name into firstname from employees2 where division_id ='SAL'; dbms_output.put_line('first_name=' || firstname); exception when too_many_rows then dbms_output.put_line('不能返回多行数据'); end; /
用户自定义异常:
以下代码演示了用户接受输入的类别。IF 语句将用户输入的类别与指定的类别相匹配。如果指定的类别中不存在将引发typeException 异常
declare typeException exception; temptype varchar2(20); begin temptype :='&type'; if temptype not in ('java','c++','c#') then raise typeException; else dbms_output.put_line('temptype = '||temptype); end if; exception when typeException then --dbms_output.put_line('没有找到相应的类型'); raise_application_error(-20000,'没有找到相应的类型'); end;
存储过程的使用:
过程是执行某些操作的子程序,它是执行特定任务的模块,它可以被赋予参数,存储在数据库中。以下代码
1. 创建存储过程语法:
CREATE [OR REPLACE] PROCEDURE <procedure name> [(<parameter list>)] IS|AS <local variable declaration> BEGIN <executable statements> [EXCEPTION <exception handlers>] END;
以下代码演示了如何创建一个不带参数的存储过程:
create or replace procedure pro_emp as firstName varchar2(20); lastName varchar2(20); salary number(20); begin select first_name,last_name,salary into firstName,lastName,salary from employees2 where employee_id = 1; dbms_output.put_line('firstName = '||firstName); dbms_output.put_line('lastName = ' ||lastName); dbms_output.put_line('salary = ' ||salary); exception when no_data_found then dbms_output.put_line('数据没有找到'); end;
执行以上存储过程:
execute pro_emp ;
过程参数模式:参数传递的模式有三种IN , OUT , IN OUT
IN 是参数的默认模式,这种模式定义的参数在程序运行的时候已经具有值,在过程序体中这个值不会改变。
OUT 模式定义的参数只在过程内部赋值。
IN OUT 模式定义的参数当过程运行时可能已经具有值,但是在过程体中也可以修改
以下创建了带参数的过程:
create or replace procedure mypro(employeeid in number,divisionid in out va rchar2,jobid out varchar2) as tempdivid varchar2(20); tempjobid varchar2(20); begin select division_id,job_id into tempdivid,tempjobid from employees2 where employee_id =employeeid; divisionid :=tempdivid; jobid :=tempjobid; end;
执行以上过程:
declare cdivisionid varchar2(20); cjobid varchar2(20); cempid number(10); begin cempid :=1; mypro(cempid,cdivisionid,cjobid); dbms_output.put_line('...... cdivisionid = '||cdivisionid); dbms_output.put_line('...... cjobid = '||cjobid); end; /
Oracle中的函数:
以下代码创建了函数:
create or replace function myfun(empid number) return varchar2 is firstName varchar2(20); lastName varchar2(20); begin select first_name,last_name into firstName,lastName from employees2 where employee_id = empid; return 'firstName = '||firstName ||' lastName = '||lastName; end; /
执行以上函数:
declare fid number(8); info varchar2(100); begin fid :=1; info :=myfunction(1); dbms_output.put_line('info ='||info); end; /