当前位置: 代码迷 >> SQL >> PLSQL错误处理和PLSQL复合类型
  详细解决方案

PLSQL错误处理和PLSQL复合类型

热度:90   发布时间:2016-05-05 14:08:12.0
PLSQL异常处理和PLSQL复合类型

*****************************************
???? PLSQL异常处理
*****************************************
1、声明异常
?异常名 EXCEPTION;
2、抛出异常
?RAISE 异常名
3、处理异常
?抛出异常后的逻辑代码不会被继续执行

异常的定义使用
??? ―――――――――――――――――――――――――――――――――――――
??? begin
???? ???? dbms_output.put_line(1/0);
??? exception
??????????? when others then
??????????????? dbms_output.put_line('error');
??? end;

?

?????declare
??????? v_val number;
??????? v_ename varchar2(20);
?????begin
?????????? select SAL,ename into v_val,v_ename from emp where EMPNO=&aa;
?????????? dbms_output.put_line( v_ename||'的工资是:'||v_val);
?????exception
????????? when no_data_found? then
??????????? dbms_output.put_line('您输入的工号有误!');
??? ?end;

?

?

?下面一个例子是程序员自己手动往外抛异常信息,raise,sqlcode,sqlerrm为关键字。

??? declare
??????????? e_myException exception;
??? begin
??????????? dbms_output.put_line('hello');
??????????? raise e_myException;
--raise手动抛出异常,用此关键字,抛出后转到自定义的e_myException ,执行其里面的putline函数后,再跳到end处,结束PL/SQL块,raise接下面的2句不会继续执行。
??????????? dbms_output.put_line('world');
??????????? dbms_output.put_line(1/0);
??? exception
??????????? when e_myException then
??????????????? dbms_output.put_line(sqlcode); --当前会话执行状态,错误编码
??????????????? dbms_output.put_line(sqlerrm); --当前错误信息
??????????????? dbms_output.put_line('my error');
??????????? when others then
??????????????? dbms_output.put_line('error');
??? end;
??? ―――――――――――――――――――――――――――――――――――――

?

*****************************************
??PLSQL复合类型
*****************************************
记录类型record

record类型最常用,声明的时候可以加not null,但必须给初始值,如果record类型一致可以相互赋值,如果类型不同,里面的字段恰好相同,不能互相赋值。引用记录型变量的方法是“记录变量名.基本类型变量名”。
? ―――――――――――――――――――――――――――――――――――――
? declare
?????? type t_first is record(
??????????? id number(3),
??????????? name varchar2(20)
?????? );
?????? v_first t_first;
? begin
???? v_first.id:=1;
???? v_first.name:='cheng';
???? dbms_output.put_line(v_first.id);
???? dbms_output.put_line(v_first.name);
? end;

? record类型变量间赋值
??declare
?????? type t_first is record(
???????? id number,
???????? name varchar2(20)??
?????? );
?????? v_first t_first;
?????? v_second t_first;
? begin
?????? v_first.id:=1;
?????? v_first.name:='susu';
??????
?????? v_second:=v_first;--相互赋值
??????
?????? v_first.id:=2;
?????? v_first.name:='kettas';
?????? dbms_output.put_line(v_first.id);
?????? dbms_output.put_line(v_first.name);
?????? dbms_output.put_line(v_second.id);
?????? dbms_output.put_line(v_second.name);
?? end;
?? ―――――――――――――――――――――――――――――――――――――
表类型变量table
语法如下:
??? type 表类型 is table of 类型 index by binary_integer;
??? 表变量名 表类型;
类型可以是前面的类型定义,index by binary_integer子句代表以符号整数为索引,这样访问表类型变量中的数据方法就是“表变量名(索引符号整数)”。table类型,相当于java中的Map容器,就是一个可变长的数组,key(符号整数索引)必须是整数,可以是负数,value(类型)可以是标量,也可以是record类型。可以不按顺序赋值,但必须先赋值后使用。

1. 定义一维表类型变量
?? ―――――――――――――――――――――――――――――――――――――
?? declare
??????? type t_tb is table of varchar2(20) index by binary_integer;
??????? v_tb t_tb;
?? begin
????? v_tb(100):='hello';
????? v_tb(98):='world';
????? dbms_output.put_line(v_tb(100));
????? dbms_output.put_line(v_tb(98));
?? end;????

?? 类型为record的表类型变量?
?? declare
??????? type t_rd is record(id number,name varchar2(20));
??????? type t_tb is table of t_rd index by binary_integer;
??????? v_tb2 t_tb;
?? begin
??????? v_tb2(100).id:=1;
??????? v_tb2(100).name:='hello';
??????? --dbms_output.put_line(v_tb2(100).id);
??????? --dbms_output.put_line(v_tb2(100).name);
??????? dbms_output.put_line(v_tb2(100).id||'??? '||v_tb2(100).name);
?? end;
?? ―――――――――――――――――――――――――――――――――――――

2. 定义多维表类型变量
该程序定义了名为tabletype1的多维表类型,相当于多维数组,table1是多维表类型变量,将数据表tempuser.testtable中recordnumber为60的记录提取出来

存放在table1中并显示。
?? ―――――――――――――――――――――――――――――――――――――
?? declare
????? type tabletype1 is table of testtable%rowtype index by binary_integer;
????? table1 tabletype1;
?? begin
?????? select * into table1(60) from tempuser.testtable where recordnumber=60;
?????? dbms_output.put_line(table1(60).recordnumber||table1(60).currentdate);
?? end;
???
?? 备注:在定义好的表类型变量里,可以使用count、delete、first、last、next、exists和prior等属性进行操作,使用方法为“表变量名.属性”,返回的是数字。
???
?? set serveroutput on
?? declare
??????? type tabletype1 is table of varchar2(9) index by binary_integer;
??????? table1 tabletype1;
?? begin
??????? table1(1):='成都市';
??????? table1(2):='北京市';
??????? table1(3):='青岛市';
??????? dbms_output.put_line('总记录数:'||to_char(table1.count));
??????? dbms_output.put_line('第一条记录:'||table1.first);
??????? dbms_output.put_line('最后条记录:'||table1.last);
??????? dbms_output.put_line('第二条的前一条记录:'||table1.prior(2));
??????? dbms_output.put_line('第二条的后一条记录:'||table1.next(2));
??? end;
??? ―――――――――――――――――――――――――――――――――――――

*****************************************
???? %type和%rowtype
*****************************************
使用%type定义变量,为了让PL/SQL中变量的类型和数据表中的字段的数据类型一致,Oracle 9i提供了%type定义方法。这样当数据表的字段类型修改后,PL/SQL程序中相应变量的类型也自动修改。
??? ―――――――――――――――――――――――――――――――――――――
??? create table student(
?????? id number,
?????? name varchar2(20),
?????? age number(3,0)
??? );

??? insert into student(id,name,age) values(1,'susu',23);
??? --查找一个字段的变量

??? declare
?????? v_name varchar2(20);
?????? v_name2 student.name%type;
??? begin
?????? select name into v_name2 from student where rownum=1;
?????? dbms_output.put_line(v_name2);
??? end;

??? --查找多个字段的变量
??? declare
??????? v_id student.id%type;
??????? v_name student.name%type;
??????? v_age student.age%type;
??? begin
????? select id,name,age into v_id,v_name,v_age from student where rownum=1;
????? dbms_output.put_line(v_id||'? '||v_name||'? '||v_age);
??? end;

??? --查找一个类型的变量,推荐用*

??? declare
?????? v_student student%rowtype;
??? begin
?????? select * into v_student from student where rownum=1;
?????? dbms_output.put_line(v_student.id||'? '||v_student.name||'? '||v_student.age);
??? end;

??? --也可以按字段查找,但是字段顺序必须一样,不推荐这样做
??? declare
?????? v_student student%rowtype;
??? begin
???? select id,name,age into v_student from student where rownum=1;
???? dbms_output.put_line(v_student.id||'? '||v_student.name||'? '||v_student.age);
??? end;

??? declare
?????? v_student student%rowtype;
??? begin
???? select id,name,age into v_student.id,v_student.name,v_student.age from student where id=1;
???? --select * into v_student.id,v_student.name,v_student.age from student where id=1;
???? dbms_output.put_line();
??? end;
??? ―――――――――――――――――――――――――――――――――――――
??? 备注:insert,update,delete,select都可以,create table,drop table不行。DPL,DML,和流程控制语句可以在pl/sql里用,但DDL语句不行。
???
??? declare
?????? v_name student.name%type:='wang';
??? begin
?????? insert into student(id,name,age) values(2,v_name,26);
??? end;
???
??? begin
?????? insert into student(id,name,age) values(5,'hehe',25);
??? end;

??? declare
?????? v_name student.name%type:='hexian';
??? begin
?????? update student set name=v_name where id=1;
??? end;

??? begin
?????? update student set name='qinaide' where id=2;
??? end;
??? ―――――――――――――――――――――――――――――――――――――

?

  相关解决方案