存储过程:
是一个命名的PL/SQL程序块,保存在数据库中,不可以被SQL语句直接执行或调用,只能通过EXECUT命令执行或在PL/SQL程序块内部被调用。由于存储过程是已经编译好的代码,所以其被调用或引用时,执行效率非常高。
例子
在当前模式下,如果数据库中存在同名的存储过程,则要求新创建的存储过程覆盖掉已存在的存储过程;如果不存在同名的存储过程,则直接创建即可
create or replace procedure pro_insertDept is/as
begin
insert into dept values(99,'市场拓展部','BEIJING');
commit;
dbms_output.put_line('插入新记录成功!');
end pro_insertDept;
/
这个存储过程,只是创建成功,insert语句仅仅是编译了,并没有被执行。若要执行这个insert语句,则需要在SQL *Plus中使用execute
执行该存储过程:execute pro_insertDept;
或者
在PL/SQL程序块中调用该存储过程:
set serverout on
begin
pro_insertDept;
end;
/
存储过程的参数
为了增强存储过程的灵活性,可以实现向存储过程传入参数。参数是一种向程序单元输入和输出数据的机制,存储过程可以接受多个参数,参数模式包括IN,OUT,IN OUT
IN参数:
创建一个存储过程,并定义3个in模式的变量,然后将3个变量的值插入到dept表中
create or replace procedure insert_dept(
num_deptno in number,
var_ename in varchar2,
var_loc in varchar2) is
begin
insert into dept
values(num_deptno,var_ename,var_loc);
commit;
end insert_dept;
/
向存储过程传入参数有3种方式:
1.指定名称传递:参数名称=>参数值
2.按位置传递:用户提供的参数值顺序必须与存储过程中定义的顺序相同。
注意:有时候在参数较多时,用户不容易记住参数的顺序和类型,用户可以通过desc命令来查看存储过程中参数的定义信息。
3.混合方式:比如 insert_dept(38,var_loc=>'济南',var_ename=>'测试部');
注意:
IN参数的默认值
var_dname in varchar2 default '综合部'
OUT参数:
创建一个存储过程,要求定义两个out模式的字符类型的参数,然后在dept表中检索到一行部门信息存储到这两个参数中
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;
exception
when no_data_found then
dbms_output.put_line('该部门编号不存在');
end select_dept;
/
执行存储过程:
variable var_dname varchar2(50);
variable var_loc varchar2(50);
exec select_dept(25,:var_dname,:var_loc);
查看输出变量:
print var_dname var_loc;
或者
select :var_dname,:var_loc from dual;
IN OUT 参数:
创建一个存储过程,在其中定义一个“in out”参数,该存储参数用来计算这个参数的平方或平方根
create or replace procedure pro_square(
num in out number,
flag in boolean) is
begin
if flag then
num:=power(num,2);
else
num:=sqrt(num);
end if;
end;
/
调用存储过程pro_square,计算某个数的平方或平方根
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;
/