PL/SQL编程_子程序设计

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PL/SQL编程_子程序设计相关的知识,希望对你有一定的参考价值。

利用PL/SQL可以进行模块化程序设计

在一个PL/SQL块中,可以定义若干个子程序

把一些功能相对独立、需要经常执行的代码定义为一个子程序,在需要时根据子程序的名字进行调用。
这样不仅便于程序设计和编码,而且利于程序的调试。
PL/SQL有两种形式的子程序,即过程和函数。

在子程序中也可以定义变量、类型、游标等,也可以进行异常处理。
在调用于程序时,可以向子程序传递参数。

过程与函数的区别在于函数具有返回值,可以向调用者返回执行结果,而过程没有返回值。

如何使用过程

子程序的定义出现在PL/SQL块的声明部分,而它的调用则出现在PL/SQL块的可执行部分。
过程的定义格式如下:

PROCEDURE 过程名称 (参数1 定义, 参数2 定义 ...)

AS 或 IS

变量声明部分

BEGIN

可执行部分

EXCEPTION

异常处理部分

END;

在过程中可以定义参数,在调用该过程时,可以向过程传递实际参数。

如果没有参数,则过程名后面的圆括号及参数列表可以省略。

参数的定义形式为:

参数名 参数传递模式 数据类型 := 默认值

其中参数名和数据类型是必不可少的部分,其他两部分是可以省略的。

参数传递模式包括INOUT以及IN OUT三种形式,其中IN是默认的传递模式,如果没有指定,则默认为IN ,它指的是从调用者向过程中传递一个实际参数。

OUT是指从过程中向调用者传递参数,如果要使用这种传递模式,则需要明确指定。

在调用过程时,过程的执行情况会影响这个变量的值。
“ IN OUT”是一种双向传递模式,一方面从调用者向过程传递参数,另一方面从过程向调用者传递结果,如果要使用这种形式,则需要明确指定。

          IN      OUT        IN OUT
形式参数的作用  一个常量  没有初始化的变量  经过初始化的变量

实际参数的形式  常量、表达式、变量  必须是一个变量  必须是一个变量

参数默认值的作用是在调用过程时,如果没有提供实际参数,则将此默认值作为实际参数传递给过程。
数据类型用来指定参数的类型,在参数定义中不能指定对参数的约束条件,即不能指定参数的长度和是否为空等属性。
在下面的PL/SQL块中定义了两个过程,其中prompt过程用于对某部门的员工增加工资和奖金,而total_income过程用于计算某部门员工的总收入和应缴的税。

DECLARE
dno number;
procedure promption(salary IN integer, commiss IN integer, d_no IN integer:=0)
IS
BEGIN
if d_no=0 then --表示所有部门
UPDATE emp
set sal=sal+salary,comm=comm+commiss;
else --仅表示指定的部门
UPDATE emp
set sal=sal+salary,comm=comm+commiss
WHERE deptno=d_no;
END if;
END;
procedure total_income(d_no IN integer:=0)
IS
empno integer;
total number;
tax number;
BEGIN
if d_no=0 then --表示所有部门
SELECT sum(sal+nvl(comm, 0)), sum(sal*0.03) INTO total,tax FROM emp;
else --仅表示指定的部门
SELECT sum(sal+nvl(comm, 0)), sum(sal*0.03) INTO total,tax
FROM emp
WHERE deptno=d_no;
END if;
dbms_output.put_line (‘总收入:‘ || total || ‘总税款: ‘ || tax) ;
END;
BEGIN --PL/SQL块的可执行部分
dno:=10;
promption(100,0,dno);
total_income(dno);
END;

在过程promption 中定义了三个参数,其中参数d_no带有默认值,这样在调用该过程时,如果没有为该参数提供实际参数,则使用默认值。
例如,在上述例子中,为部门10 中的员工增加了100元工资。
如果采用下面的调用形式,则为所有部门的员工增加100元工资:

promption(100, 0);

在调用过程时,需要为过程中的参数提供实际参数,它们在顺序上是对应的。

为了保证将参数正确地传给过程,要求在定义过程时,将所有带默认值的参数集中放在参数列表的右边。
因为只有这样才能将其他实际参数一对一地赋给前面的不带默认值的参数。
如果过程有多个参数,在调用过程时,也可以不按照参数列表的顺序提供实际参数,这时需要两种参数之间的对应关系。

例如,过程promption可以采用以下调用形式:
promption(d_no=>dno,commiss=>0, salary=>100);

过程total_inco1ne 中的参数d_no也带有默认值,这样在调用该过程时,如果提供了实际参数,则计算指定部门的员工总收入和总税款,如果采用以下调用形式:

total_income ( ) ;

则计算所有部门的员工总收入和总税款。
在上述两个过程中,所有参数的传递模式都是IN ,即把实际参数从调用者传递给过程。

这种形式是默认的,可以省略的关键字。
如果需要把过程的执行情况反映给调用者,则需要使用OUT形式,或者“ IN OUT”形式。
例如,为了计算员工总收入和总税款,并把结果反映到主程序中,对过程total_ income进行了一些改造,增加了两个参数,传递模式都是OUT 。
改造后的PL/SQL块代码如下:

DECLARE
dno number;
abed number;
xyz number;
procedure total_income(d_no IN integer,total OUT number,tax OUT number)
AS
empno integer;
BEGIN
if d_no=0 then --表示所有部门
SELECT sum(sal+nvl(comm,0)), sum(sal*0.03) INTO total,tax FROM emp;
else --仅表示指定的部门
SELECT sum(sal+nvl(comm,0)), sum(sal*0.03) INTO total,tax
FROM emp
WHERE deptno=d_no;
END if;
END;
BEGIN
dno:=10;
--PL/SQL块的可执行部分
total_income(dno,abed,xyz);
dbms_output.put_line (‘总收入: ‘ || abed || ‘ 总税款: ‘ || xyz ) ;
END;

在调用过程total_income时,提供了三个实际参数,其中参数abed和xyz没有实际的值即使有,在这里也不起任何作用,因为这两个参数的传递模式是OUT过程在执行时,将参数total和tax的值传分别赋给abed和xyz ,这样就将过程中的数据传给了调用者。
注:IN类型参数是不能作为变量赋值的。

 

以上是关于PL/SQL编程_子程序设计的主要内容,如果未能解决你的问题,请参考以下文章

Oracle之PL/SQL编程

Oracle | PL/SQL编程

PL/SQL编程_存储程序

PL/SQLPL/SQL过程

PL/SQL编程_概述

pl/sql