(一)存储过程(procedure)
对于PLSql程序的使用,如果每次使用都要进行编写,会非常的麻烦,这时可以采用过程和函数来命名PLSQL程序,被编译后存储到数据库中,以备后续使用。
过程和函数统称为PL/SQL子程序,他们是被命名的PL/SQL块,均存储在数据库中,并通过输入、输出参数或输入/输出参数与其调用者交换信息。过程和函数的唯一区别是函数总向调用者返回数据,而过程则不返回数据。
在编译存储过程报错时,可以使用show error命令查看具体错误原因。
(二)存储过程格式
create or replace procedure存储过程名(
para1varchar2,
para2 outvarchar2,
para3in out varchar2)as|is //is与as一样的作用v_namevarchar2(20);beginv_name :='zhangsf';
para3 :=v_name;
dbms_output.put_line('para3:'||para3);
end;
上面就是一个最简单的存储过程。一个存储过程大体分为这么几个部分:
1、创建语句:create or replace procedure 存储过程名
如果没有or replace语句,则仅仅是新建一个存储过程。如果系统存在该存储过程,则会报错。Create or replace procedure 如果系统中没有此存储过程就新建一个,如果系统中有此存储过程则把原来删除掉,重新创建一个存储过程。
2、存储过程名定义:包括存储过程名和参数列表。
参数名和参数类型。参数名不能重复, 参数传递方式:IN, OUT, IN OUT
IN 表示输入参数,按值传递方式。
OUT 表示输出参数,可以理解为按引用传递方式。可以作为存储过程的输出结果,供外部调用者使用。
IN OUT 即可作输入参数,也可作输出参数。
参数的数据类型只需要指明类型名即可,不需要指定宽度。
参数的宽度由外部调用者决定。
过程可以有参数,也可以没有参数
3、变量声明块:紧跟着的as (is )关键字,可以理解为pl/sql的declare关键字,用于声明变量。
变量声明块用于声明该存储过程需要用到的变量,它的作用域为该存储过程。另外这里声明的变量必须指定宽度。遵循PL/SQL的变量声明规范。
4、过程语句块:从begin 关键字开始为过程的语句块。存储过程的具体逻辑在这里来实现。
5、异常处理块:关键字为exception ,为处理语句产生的异常。该部分为可选
6、结束块:由end关键字结果。
7、一般,只有在确认function_name函数是新函数或是要更新的函数时,才使用OR REPALCE关键字,否则容易删除有用的函数。
8、IN,OUT,IN OUT是形参的模式。若省略,则为IN模式。IN模式的形参只能将实参传递给形参,进入函数内部,但只能读不能写,函数返回时实参的值不变。OUT模式的形参会忽略调用时的实参值(或说该形参的初始值总是NULL),但在函数内部可以被读或写,函数返回时形参的值会赋予给实参。IN OUT具有前两种模式的特性,即调用时,实参的值总是传递给形参,结束时,形参的值传递给实参。调用时,对于IN模式的实参可以是常量或变量,但对于OUT和IN OUT模式的实参必须是变量。
(三)执行存储过程、函数
exec 存储过程名(函数);
或者
begin
存储过程名;
end;
(四)函数(与存储过程类似)
CREATE[OR REPLACE]FUNCTIONfunction_name
(arg1[{ IN | OUT | IN OUT }]type1[DEFAULT value1],[arg2 [ { IN | OUT | IN OUT }]type2[DEFAULT value1]],
......[argn [ { IN | OUT | IN OUT }]typen[DEFAULT valuen]])[AUTHID DEFINER | CURRENT_USER]RETURNreturn_typeIS|ASBEGIN执行部分RETURNexpression
EXCEPTION
异常处理部分END;
(五)实例
create or replace procedure p
is
cursor c
is
select * from emp2 for update;
begin
for v_temp in c loop
if (v_temp.deptno = 10) then
update emp2 set sal = sal + 10 where current of c;
elsif (v_temp.deptno = 20) then
update emp2 set sal = sal + 20 where current of c;
else
update emp2 set sal = sal + 50 where current of c;
end if;
end loop;
commit;
end;
--执行
exec p;
或
begin;
p;
end;
--带参数的存储过程
create or replace procedure p
(v_a in number, v_b number, v_ret out number, v_temp in out number)
is
begin
if (v_a > v_b) then
v_ret := v_a;
else
v_ret := v_b;
end if;
v_temp := v_temp + 1;
end;
--实验
declare
v_a number := 3;
v_b number := 4;
v_ret number; //用来保存函数的输出结果,供调用者使用
v_temp number := 5;
begin
p(v_a, v_b, v_ret, v_temp); //直接调用函数并出入参数
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
-------------------
--函数
create or replace function sal_tax
(v_sal number)
return number
is
begin
if (v_sal < 2000) then
return 0.10;
elsif (v_sal < 2750) then
return 0.15;
else
return 0.20;
end if;
end;
--查询oracle中的存储过程:
方法一:select * from user_procedures;方法二:select object_name,object_type,procedure_name from dba_procedures where object_type='PROCEDURE' and owner='SCOTT';
select name from user_source where type='PROCEDURE';
或者:
select object_name from user_procedures;
或者:
select object_name from user_objects where object_type='PROCEDURE' ;
②找到你所要查询的存储过程名字后,执行下面操作,可以看到存错过程内容:
select text from user_source where name ='xxxx';--(xxxx代表所要查询的存储过程名字)
------------------------------------------------
如果是函数,类似的方法,只需要把PROCEDURE,换成FUNCTION即可
删除存储过程和函数
drop procedure 存储过程名;
drop function 函数名;