Oracle存储过程
存储过程:
所谓存储过程stored procedure,就是一组用于完成数据库特定功能的SQL语句集。包含三个部分,过程声明、执行过程部分、存储过程异常。
带参数存储过程含赋值方式:
create or replace procedure ProcedureName(isal in emp.sal%type,
sname out varchar,
sjob in out varchar)
as
icount number;
begin
select count(*) into icount from emp where sal>isal and job=sjob;
if icount=1 then
....
else
....
end if;
exception
when too_many_rows then
DBMS_OUTPUT.PUT_LINE('返回值多于1行');
when others then
DBMS_OUTPUT.PUT_LINE('在RUNBYPARMETERS过程中出错!');
end;
* 1、参数in表示输入参数,是参数的默认形式;
Out表示返回值参数,类型可以使用oracle中的合法类型,out模式定义的参数只能在过程体内部赋值,表示该参数可以将某个值传递回调用他的过程;
In out表示该参数可以向该过程中传递值,也可以将某个值传出去。
2、isal in emp.sal%type,就是指isal这个变量引用了表emp中sal字段的类型, 如果emp表中sal的类型变了,isal这个字段的类型也会跟着变化,总之,isal和表emp中sal字段类型一致。引用型变量可以不用知道该表中类型是什么,只要引用的表中的字段类型改变,定义的变量就跟着改变, 用引用型变量易于维护。
存储过程的调用(sql命令行方式下):
1、SQL> exec proc_emp('参数1','参数2’');//无返回值方式调用
2、SQL> val vsal number
SQL> exec proc_emp(‘参数1’,:vsal);//有返回值方式调用,这个时候exec可改成call。
建立一个存储过程:
create or replace procedure firstProc as begin dbms_output.put_line('Hello,World!'); end;
* dbms_output.put_line('Hello,World!');是一个输出语句
在数据库执行上面这个存储过程:
desc firstProc();
end;
* 输出结果是 Hello,World!
定义变量,进行运算,输出一个Count所用的时间:
create or replace procedure testTime as n_start number; n_end number; samplenum number; use_time number; begin n_start:=dbms_utility.get_time; select count(*) into samplenum from emp; n_end:=dbms_utility.get_time; use_time:=n_end-n_start; dbms_output.put_line('this statement cost'||use_time||'miliseconds'); end;
* dbms_uitity.get_time记录当前时刻的时间(单位是毫秒),主要用于计算SQL、过程等的执行时间,一般是记下开始和结束时间,相减后除以100就是所经历时间(单位是秒)。
给存储过程赋值:
//创建
create or replace procedure testProc(nums in number) as begin dbms_output.put_line('the put number is'||nums) end; //执行 declare n number begin n:=1; testProc(nums>=n); end;
下面按照增删改查的顺序创建存储过程
插入(增):
create or replace procedure Proc_test_Insert_single( e_no in number, e_name in varchar, s in varchar, d in varchar) as begin insert into emp (emp_id,emp_name,salary,birthday) value(e_no,e_name,a,s); end;
调用:
declare i number; n varchar(5); s varchar(11), d varchar(10); begin i:=10; n := 'text11'; st:='3998'; dt:='1998-02-02'; Proc_test_Insert_single(e_no=>i,e_name=>n,s=>st,d=>dt); end;
* 调用存储过程声明varchar时,必须限定长度,即斜体的部分不能少。同时如果给变量赋值时大于限定的长度了,则会提示ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小
更新(改):
create or replace procedure Proc_test_update_single( e_no in number s in varchar) as begin update emp set salary=s where emp_id=e_no; end;
调用:
declare n in number; st in varchar(11); begin n := 2; st:=3998; Proc_test_update_single(e_no=>n,s=>st); end;
更新,将一张表的id字段,查询出来更新到另外一张表:
create or replace procedure update_line as bs varchar(20); kgn varchar(20); bid number; cursor c_db is select b_id,b_bs.b_kgn from pmdcdb; begin from temp in c_db loop update yygz_db set b_id=temp.b_id where g_bs=temp.b_bs and g_bh=temp.b_kgh; end loop; end;
调用:
begin
update_line;
end;
*1、cursor c_db是定义一个游标,获得查询语句的结果集;
2、 For temp in c_bd loop
Begin
End;
End loop
是循环游标,其形式类似于C#中的foreach
查询(查):
create or replace procedure Proc_text_select_single( t in varchar, r out varchar) as begin select salary into r from emp where emp_name=t; end;
调用:
declare T varchar(4); R varchar(4); begin T:='zz'; Proc_text_select_single(t=>T,r=>R) dbms_output.put_line('R='||R); end;
* 这个存储过程使用了2个参数,并分别出现了IN和OUT,in代表输入,out用于输出,从下面的语句也可以看到salary写入到变量r中了,这个r我们可以在调用存储过程后得到。