当前位置:文档之家› Oracle 存储过程参数

Oracle 存储过程参数

Oracle存储过程参数在创建存储过程时,需要考虑的一件重要事情就是过程的灵活性,以方便随后可以重新使用。

通过使用“参数”可以使程序单元变得很灵活,参数是一种向程序单元输入和输出数据的机制,存储过程可以接受和返回0到多个参数。

Oracle有三种参数模式:IN、OUT和IN OUT。

1.IN参数该类型的参数值由调用者传入,并且只能够被存储过程读取。

这种模式的参数是最常用的,也是默认的参数模式。

例如,下面以SCOTT用户连接到数据库,并建立一个简单的存储过程ADD_EMPLOYEE。

顾名思义,该过程将接受一系列参数,并且将它们添加到SCOTT.EMP 表中:SQL> create or replace procedure add_employee(2 id_param in number,3 name_param in varchar2,4 job_param in varchar2,5 hire_param in date,6 salary_param in number) is7 begin8 insert into scott.emp(empno,ename,job,hiredate,sal)9 values(id_param,name_param,job_param,hire_param,salary_param);10 end add_employee;11 /过程已创建。

在为存储过程定义参数时,参数的数据类型不能包括大小和精度信息。

在调用该存储过程时,用户需要传递一系列参数,以便过程的执行部使用这些参数向SCOTT.EMP表添加一条记录。

在调用存储过程时有三种向其传递参数的方法:名称表示法、位置表示法和混合表示法。

名称表示法名称表示法是指为各个参数传递参数值时,指定传入数值的参数名。

使用名称表示法传递参数的语法形式如下:prcedure_name(param_name=>value[,param_name=>value]);例如,在下面的示例中使有名称表示法传递参数,以调用存储过程ADD_EMPLOYEE:SQL> alter session set nls_date_format = 'yyyy-mm-dd';会话已更改。

SQL> begin2 add_employee(id_param=>8000,name_param =>'ATG',3 job_param =>'CLERK',hire_param =>'1997-12-20',4 salary_param =>1500);5 end;6 /PL/SQL 过程已成功完成。

通过名称传递法传递参数的好处:规定了各个值被赋予哪个参数。

由于明确指定了向各个参数传递的值,因此在调用过程时就不再需要考虑创建过程时定义的参数顺序。

在使用名称表示法时,如果参数命名合理,这可以方便用户阅读、查阅以及调试代码。

下面使用打乱次序的参数调用过程,查看它是否能够正常运行:SQL> exec add_employee(name_param =>'LI',job_param =>'CLERK',hire_param =>'1999-10-20',id_param=>8120,salary_param =>1500);SQL> select empno,ename,job,hiredate,sal2 from emp3 where empno>8000;● 位置表示法当参数比较多时,通过名称表示法调用过程时可能会非常长。

为了克服名称表示法的弊端,可以采用位置表示法。

采有位置表示法传递参数时,用户提供的参数值顺序必须与过程中定义的参数顺序相同。

例如,下面的程序使用位置表示法传递参数调用ADD_EMPLOYEE 过程:SQL> exec add_employee(8021,'刘丽','SALESMAN','1995-10-17',2000);PL/SQL 过程已成功完成。

前面说过,存储过程会被保存在数据库中,这也就意味着,可以像使用DESCRIBE 命令列出表的结构一样,可以使用DESCRIBE 命令列出关于存储过程的详细信息。

在调用存储过程时,可以使用DESCRIBE 命令来查看过程定义的参数次序是否相同。

● 混合表示法从上面的示例可以看出,位置表示法和名称表示法各有自己的优缺点,为了弥补这两者的不足,还可以采用混合表示法发挥两者的优点。

下面的示例是采用了混合表示法调用存储过程ADD_EMPLOYEE :SQL> exec add_employee(8022,'王芳',hire_param =>'1996-11-17',job_param=>'clerk',salary_param=>3000)PL/SQL 过程已成功完成。

在上面的程序中,两个参数采用了位置表示法传递值,随后则切换为名称表示法传递参数。

当切换为名称表示法传递参数后,在后续的参数也必须使用名称表示法。

这就说,当ADD_EMPLOYEE 过程的第3个参数采用名称表示法传入值时,其第4、5个参数也必须使用名称表示法。

2.OUT 参数OUT 类型的参数则由存储过程传入值,然后由用户接收参数值。

下面通过SCOTT.EMP 表创建一个搜索过程,该过程将根据提供的EMPNO 列的值,检索雇员的ENAME 和SAL :注 意 在使用位置表示法传递参数调用过程时,用户需要确定过程中定义参数的次序,如果传递参数的次序与定义时的次序不相同,则调用过程时可能会失败,也可以得到非常难以预料的结果。

SQL> create or replace procedure search_employee(2 empno_param in number,3 name_param out emp.ename%type,4 salary_param out emp.sal%type) is5 begin6 select ename,sal7 into name_param,salary_param8 from scott.emp9 where empno=empno_param;10 exception11 when no_data_found then12 name_param:='NULL';13 salary_param:= -1;14 dbms_output.put_line('未找到指定编号的员工信息!');15 end search_employee;16 /过程已创建。

因为过程要通过OUT参数返回值,所以在调用它时必须提供能够接受返回值的变量。

因此,可以在编写PL/SQL匿名程序块时需要定义两个变量接收返回值,而在使用SQL*Plus 调用过程时,需要使用V ARIABLE命令绑定参数值。

下面的语句是在SQL*Plus中使用VARIABLE命令绑定参数值,并调用存储过程SEARCH_EMPLOYEE:SQL> variable name varchar2(10);SQL> variable sal number;SQL> exec search_employee(7499,:name,:sal);PL/SQL 过程已成功完成。

为了查看执行结果,可以在SQL*Plus中使用PRINT命令显示变量值:SQL> print nameNAME---------------------ALLENSQL> print salSAL---------------1600也可以通过如下的SELECT语句检索绑定的变量值:SQL> select :name,:sal2 from dual;:NAME :SAL-------------------------------- ----------ALLEN 1600在匿名程序块中调用存储过程SEARCH_EMPLOYEE的形式如下:SQL> set serverout onSQL> declare2 name emp.ename%type;3 sal emp.sal%type;4 begin5 search_employee(7499,name,sal);6 dbms_output.put('姓名:' || name);7 dbms_output.put_line(' 薪金:' || sal);8 end;9 /姓名:ALLEN 薪金:1600PL/SQL 过程已成功完成。

需要注意,在调用具有OUT参数的过程时,必须为OUT参数提供变量,即使OUT参数在过程中没有设置返回值,调用时也必须为其提供接受变量,否则调用过程是将会因为返回值将无法保存而出现错误。

如果用户使用常量或表达式调用这种类型的过程时,系统将出现如下的错误:SQL> set serverout onSQL> declare2 name emp.ename%type;3 begin4 search_employee(7499,name,1200);5 end;6 /search_employee(7499,name,1200);*第 4 行出现错误:ORA-06550: 第4 行, 第29 列:PLS-00363: 表达式'1200' 不能用作赋值目标ORA-06550: 第4 行, 第3 列:PL/SQL: Statement ignored3.IN OUT参数对于IN参数而言,它可以接收一个值,但是不能在过程中修改这个值。

而对于OUT 参数而言,它在调用过程时为空,在过程的执行中将为这参数指定一个值,并在执行结束后返回。

而IN OUT类型的参数同时具有IN参数和OUT参数的特性,在调用过程时即可以向类型的参数传入值,也可以从该参数接收值;而在过程的执行中即可以读取又写入该类型参数。

使用这种类型参数的一个典型示例就是交换两个数的位置,如下面的程序实现了交换两个数据的位置:SQL> create or replace procedure swap(2 num1_param in out number,3 num2_param in out number) is4 var_temp number;5 begin6 var_temp:=num1_param;7 num1_param:=num2_param;8 num2_param:=var_temp;9 end swap;10 /过程已创建。

相关主题