使用存储过程和函数的一个重要方面是,能够将数据从调用程序传递给存储过程或函数,并能够从存储过程或函数接收回数据。这将通过使用参数来实现。

参数在存储过程或函数定义中声明,在存储过程或函数名称后面用圆括号(())括起。在存储过程或函数定义中声明的参数称为形参。当调用存储过程或函数时,调用程序提供要在被调用程序处理中使用的实际数据,以及要接收被调用程序处理结果的变量。调用程序在调用存储过程或函数时提供的数据和变量称为实参。

下面是形参声明的常规格式。

(name [ IN | OUT | IN OUT ] data_type [ DEFAULT value ])
  • name 是分配给形参的标识符。如果指定,IN 定义用于接收输入数据并将其保存到存储过程或函数的参数。
  • IN 参数也可初始化为默认值。如果指定,OUT 定义用于从存储过程或函数返回数据的参数。如果指定,IN OUT 允许参数既用于输入也用于输出。如果 IN、OUT 和 IN OUT 全都被省略,则参数的行为与默认情况下它定义为 IN 时的相同。无论参数是 IN、OUT 还是 IN OUT,都统称为参数模式。
  • data_type 定义参数的数据类型。
  • value 是在调用中未指定实参时,在被调用程序中分配给 IN 参数的默认值。

示例

下面是一个采用参数的存储过程的示例:

CREATE OR REPLACE PROCEDURE emp_query (
    p_deptno        IN     NUMBER,
    p_empno         IN OUT NUMBER,
    p_ename         IN OUT VARCHAR2,
    p_job           OUT    VARCHAR2,
    p_hiredate      OUT    DATE,
    p_sal           OUT    NUMBER
)
IS
BEGIN
    SELECT empno, ename, job, hiredate, sal
        INTO p_empno, p_ename, p_job, p_hiredate, p_sal
        FROM emp
        WHERE deptno = p_deptno
          AND (empno = p_empno
           OR  ename = UPPER(p_ename));
END;

在此示例中,p_deptno 是 IN 形参,p_empno 和 p_ename 是 IN OUT 形参,p_job、p_hiredate 和 p_sal 是 OUT 形参。

说明 在上一示例中,没有在 VARCHAR2 参数中指定最大长度,并且没有在 NUMBER 参数中指定精度和小数位数。在参数声明中指定长度、精度、小数位数或其他约束是非法的。这些约束自动从调用存储过程或函数时使用的实参继承。

emp_query 存储过程可由另一个程序调用,从而将实参传递给该程序。下面是调用 emp_query 的另一个 SPL 程序的示例。

DECLARE
    v_deptno        NUMBER(2);
    v_empno         NUMBER(4);
    v_ename         VARCHAR2(10);
    v_job           VARCHAR2(9);
    v_hiredate      DATE;
    v_sal           NUMBER;
BEGIN
    v_deptno := 30;
    v_empno  := 7900;
    v_ename  := '';
    emp_query(v_deptno, v_empno, v_ename, v_job, v_hiredate, v_sal);
    DBMS_OUTPUT.PUT_LINE('Department : ' || v_deptno);
    DBMS_OUTPUT.PUT_LINE('Employee No: ' || v_empno);
    DBMS_OUTPUT.PUT_LINE('Name       : ' || v_ename);
    DBMS_OUTPUT.PUT_LINE('Job        : ' || v_job);
    DBMS_OUTPUT.PUT_LINE('Hire Date  : ' || v_hiredate);
    DBMS_OUTPUT.PUT_LINE('Salary     : ' || v_sal);
END;

在此示例中,v_deptno、v_empno、v_ename、v_job、v_hiredate 和 v_sal 是实参。

上一示例的输出如下所示:

Department : 30
Employee No: 7900
Name       : JAMES
Job        : CLERK
Hire Date  : 03-DEC-81
Salary     : 950