什么是存储过程
存储过程是一种命名的PL/SQL程序块,既可以没有参数也可以有若干个输入,输出参数,但是它通常没有返回值。存储过程被保存在数据库中,可以被SQL语句直接调用,只能通过EXECUT命令或者在PL/SQL程序块内部被调用。由于存储过程是已经编译好的代码,因此被调用或者引用时,执行效率非常高。
创建存储过程
示例如下:
create or replace procedure pro_name (parameter1,parameter2) is
begin
plsql_sentences;
[exception]
[dowith_sentences;]
end [pro_name];
注意一下,is和as的区别:在Oracle的存储过程和函数中,其实IS和AS是同义词,没有什么区别。还有在自定义类型(TPYE)和包(PACKAGE)时,使用IS和AS也并没有什么区别。但是在创建视图(VIEW)时,只能使用AS而不能使用IS。在声明游标(CURSOR)时,只能使用IS而不能使用AS。
pro_name:存储过程名字,parameter1存储过程的参数;plsql_sentences:PL/SQL语句,它是存储过程实现的主体。dowith_sentences:异常处理语句。中括号[]是可有可无的
创建一个插入的存储过程示例:
SQL> create or replace procedure pro_insertDept is
begin
insert into dept values(77,'市场拓展部','JJ');
commit;
dbms_output.put_line('插入的新记录成功!');
end pro_insertDept;
/
注意:在PL/SQL的命令窗口里面必须用“/”强制退出
调用存储过程的示例如下:
SQL> execute pro_insertDetp; --执行的存储过程
或者如下:
SQL> set serverout on; --这个只能在SQL PLUS里面使用,意思是在窗口里显示服务器输出信息
SQL> begin
pro_insertDept;
end;
/ --强制退出命令
注意:set serverout on; --这个只能在SQL PLUS里面使用,意思是在窗口里显示服务器输出信息
存储过程的参数
IN模式参数:这是一种输入类型的参数,参数值有调用方传入,并且只能被存储过程读取。这种模式是最常用的,关键字in位于参数名称之后。
SQL> create or replace procedure insert_dept(
num_deptno in number,
var_ename in varchar2,
var_loc in varchar2
) is
begin
isnert into dept values (num_deptno,var_ename,var_loc);
commit;
end insert_dept;
/
注意一下:参数类型的不能指定长度。
- 指定名称传递:指在向存储过程传递参数的时需要指定参数名称(与顺序无关,但名字要一致),即参数名称在左侧,中间是赋值符号“=>”,右侧是参数值
SQL>begin
insert_dept(var_ename=>'采购部',var_loc=>'成都',num_deptno=>15);
end;
/
- 按位置传递:提供的参数数值顺序必须与存储过程中定义的参数顺序相同
SQL>begin
insert_dept(28,'工程部','洛阳');
end ;
/
- 混合方式传递: 混合方式及时将两种结合到一起,兼顾两者的有点
混合方法需要注意:上面两种调用方式可混合使用,但是注意,一旦某个参数有使用命名符,则后面所有的参数都得使用命名符, 否则会导致异常:“PLS-00312:一个定位相关参数没有说明其相关性”
in 参数的默认值:是在声明时初始化默认值,用default关键字
SQL>create or replace procedure insert_dept(
num_deptno in numnber,
var_dname in varchar2 default '综合部',
var_loc in varchar2 default '北京'
) is
begin
insert into dept values(num_deptno,var_dname,var_loc);
end;
/
out模式参数:输出类型参数,关键字out位于参数名称之后
创建示例:
SQL> create or replace procedure select_dept(
num_deptno in number,
var_dname out dept.dname%type,
var_loc out dept.loc%type
) is begin
select dname,loc into var_dname,var_loc from dept
where deptno = num_deptno;
end select_dept;
/
注意一下:SELECT INTO 语句从一个表复制数据,然后把数据插入到另一个新表中。
(1)在PL/SQL块中调用out模式的存储过程,需要在PL/SQL块declare部分定义与存储过程中out参数类型兼容的若干变量
SQL>set serverout on
SQL> declare
var_dname dept.dname%type;
var_loc dept.loc%type;
begin
select _dept(99,var_dname,var_loc);
dbms_output.putline(var_dname||'位于:'||var_loc);
end;
/
注意:select_dept(num_deptno=>99,var_dname,var_loc),这样写会报错:一个定位相关参数没有说明其相关性,必须这样写:select_dept(num_deptno=>99,var_dname=>var_dname,var_loc=>var_loc);=>左边的是参数名,要和存储过程内部一致,右侧是参数值。
(2)用exec命令执行out模式的存储过程,在SQL*Plus环境中使用variable关键字声明两个变量,用以存储out参数的返回值
例如:
SQL>variable var_dname varchar2(50);
SQL>variable var_loc varchar2(50);
SQL>exec select_dept(15,:var_dname,:var_loc);
但是用户看不到var_dname和var_loc的值,可以通过print或者select查看
SQL>print var_dname var_loc;
select :var_dname,:var_loc from dual;
- 使用print命令查看
- 使用select语句检索绑定的变量值
IN OUT 模式参数:在执行存储过程中,in参数不能被修改,只能根据被传入的指定值为存储过程提供数据,而out类型只能等待被赋值,IN out 参数可以兼顾两者的优点,在调用的时候,从外界向该类型的参数传入值,执行完之后,将结果返回值传给外界
in out 参数示例:
SQL>create or replace procedure pro_square(
num in out number,
flag in boolen
) is i int :=2;
begin
if flag then
num :=power(num,i);
else
num :=sqrt(num);
end if;
end;
/
调用如下:
SQL>declare var_number number;
var_temp number;
boo_flag boolean;
begin
var_temp :=3;
var_number :=var_temp;
boo_flag :=false;
pro_square(var_number,boo_flag);
if boo_flag then
dbms_output.put_line(var_temp||'的平方是:'var_number);
else
dbms_output.put_line(var_temp||'的平方根是:'var_number);
end if;
end;
/