プロシージャと関数を使用する際の重要な点は、呼び出し側のプログラムからプロシージャまたは関数にデータを渡し、プロシージャまたは関数からデータを受け取る動作です。 この動作はパラメーターによって行います。

パラメーターは、プロシージャまたは関数定義内のプロシージャまたは関数名に続く括弧 () 内で宣言されます。 プロシージャまたは関数の定義で宣言されたパラメーターは、仮パラメーターです。 プロシージャまたは関数が呼び出されるとき、呼び出し側プログラムは、呼び出すプログラムの処理で使用される実際のデータと、呼び出すプログラムの処理結果を受け取る変数を提供します。 プロシージャまたは関数を呼び出すときに呼び出し側プログラムによって提供されるデータと変数は、実パラメーターです。

以下に、仮パラメーター宣言の一般的な形式を示します。

(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