如果想要dbms_output.put_line()等方法的输出能够在客户端看见的话,请
set serverouput on;
例子:
declare
empname emp.ename%type;
sno emp.empno%type;
iCount int:=0;
begin
sno:='7369';
empname:='jade';
dbms_output.put_line('employee no is '||sno||' employee name is '||empname);
select empno,ename into sno,empname from emp where empno='7369';
dbms_output.put_line('employee no is '||sno||' employee name is '||empname);
select count(*) into iCount from emp where sal>2000;
if iCount>0 then
dbms_output.put_line('有工资大于2000的人的信息'||iCount);
else
dbms_output.put_line('没有');
end if;
end;
/
异常
如同JVM一样,Oralce是最终异常处理人员;但是他们的处理结果对用户而言是不好理解的,因为他们的语言是如此地不友好,如此的ugly;
所以我们最好是自己捕获处理异常;
步骤:
1.声明异常
2.引发异常
3.处理异常
类型:
1, 预定义的异常:不需要显式声明;dbms_standard程序包里有定义;
例子: dbms_output.put_line('employee job is '||empjob);
exception
when no_data_found then
dbms_output.put_line('no data return');
如果不处理异常,程序就会报告Error而不是异常,不同于Java;
但是程序流程是一样的,出错后,后面的代码都不再执行,直接退出;
用户处理的话,出错后,处理后,其他的可以继续执行错误处理后面的代码,这和Java一样;
When others then
处理动作;
这里的others表示未知的异常发生时;这是个很保险的方法,类似用Exception的效果;其他的异常都是others的一个子类型;
2, 非预定义的异常:数据库本身不知道不能控制的,比如操作系统崩溃;
Oralce服务器错误
网络或者机器I/O错误
3, 用户定义的异常:有个类型叫exception类型
例子:
1 declare
2 dup_value exception;
3 icount int:=0;
4 begin
5 select count(*) into icount from place
6 where placeid='001';
7 if icount>0 then
8 raise dup_value;
9 end if;
10 exception
11 when dup_value then
12 dbms_output.put_line('already have the note');
13* end;
already have the note
但是我们也看到了,我们在这里定义了这样一个异常,但是当我们insert into一个’001’时,系统还是会发生系统的那个异常而不是我们定义的,解决的方法就是预条件编译:
1 declare
2 dup_value exception;
3 pragma exception_init(dup_value,-1); ---这句的意思就是异常时用我已
定义的dup_value来处理;
4 begin
5 insert into place values('001','jfka');
6 exception
7 when dup_value then
8 dbms_output.put_line('already have the note');
9* end;
already have the note
put_line只能返回给sql_plus;
raise_application_error函数的作用:
实际上,前面我们的做法只是在发生异常的时候打印了异常信息,并没有引发系统级的异常所以客户端也看不到我们打印的异常信息,但是raise_appliction_error就是直接引发系统异常而不是简单地打印错误消息:
6 exception
7 when dup_value then
8 raise_application_error(-20001,'already have the note');
9 --只能在sql/plus 中看:dbms_output.put_line('already have the note');
10* end;
declare
*
ERROR λÓÚµÚ 1 ÐÐ:
ORA-20001: already have the note
ORA-06512: ÔÚline 8
Raise_appliction_erro(-20000-> -20999,’消息’)
游标
服务器端的一个区域的一个指针;
因为在服务器端存储,所以开启游标的时候,我们在使用服务器端的资源;
好处:
1, 减少了网络流量:可以在服务器端做数据处理工作;
2, 可以实现遍历,可以对一个结果集进行逐行检索;
3, 允许直接更新表;
类型:
1,静态游标:由用户定义,任务明确,代码被编译后固定存储;
隐式游标是用户执行DML语句时,系统在服务器端自动打开的,将用户操作的数据存储在游标区域,用户执行完DML语句时,游标被自动关闭;
我们可以利用的四个属性:%notfound %found %rowcount %isopen,用来表示DML语句的执行情况;
隐式游标的名字都叫做sql,例子:
1 begin
2 insert into place values('006','beijing');
3 dbms_output.put_line('Rowcount:'||sql%rowcount);
4 if sql%notfound then
5 dbms_output.put_line('notfound is true');
6 else
7 dbms_output.put_line('notfound is false');
8 end if;
9 if sql%found then
10 dbms_output.put_line('found is true');
11 else
12 dbms_output.put_line('found is false');
13 end if;
14 if sql%isopen then
15 dbms_output.put_line('isopen is true');
16 else
17 dbms_output.put_line('isopen is false');
18 end if;
19* end;
Rowcount:1 ---统计所影响的行数
notfound is false -
found is true --和notfound都表示是否操作成功了,可以认为rocount>=1时就表示成功
isopen is false --隐式游标是否打开了?这里因为SQL执行结束后,自动关闭了;
显式游标是用户用代码定义,维护的;
注意,这样的游标是要声明的,但它是一个存储区域而不是变量;
游标标识符只不能赋值与传值,就象指针一样;
游标区域实际是个结果集,所以可以用查询语句来声明游标;
Cursor 游标名 is select * from emp;
Open,fetch,close方法用来操作;
declare
cursor empCur is select * from emp;
emprow emp%rowtype;
begin
open empCur;
fetch empCur into emprow; --fetch一次提走一行,remove的效果;
dbms_output.put_line('no'||emprow.empno||'ename'|| emprow.ename);
close empCur;
end;
/
如果有多个