関数とプロシージャの違い
いまわかる範囲だとこれぐらい。色々さわってみれば他にでてくるかも。
- 戻り値が1つだけの場合、ファンクション
- 戻り値が0またま2つ以上の場合、プロシージャ
ファンクションの構文
FUNCTION ファンクション名(引数の宣言)
RETURN 戻り値の型 IS
[宣言部]
BEGIN
[実行部]
EXCEPTION
[例外処理]
END ★ファンクション名;
★は任意で省略可能。ENDに名前を付けておくことで可読性があがるとのことだが、個人的にはインデントをしっかりしてればいらないかなぁと思う。逆にファンクション名で検索したときに、検索結果に引っかかってくるので邪魔になりそう。
プロシージャの構文
PROCEDURE プロシージャ名(引数の宣言)
[宣言部]
BEGIN
[実行部]
EXCEPTION
[例外処理]
END ★プロシージャ名;
★は任意で省略可能。ENDに名前を付けておくことで可読性があがるとのことだが、個人的にはインデントをしっかりしてればいらないかなぁと思う。逆にプロシージャ名で検索したときに、検索結果に引っかかってくるので邪魔になりそう。
プログラムサンプル
DECLARE
--宣言部
--変数の宣言
wk_ename EMP.ENAME%TYPE;
--カーソルの宣言
CURSOR q01Selector IS
SELECT
EMPNO
FROM
EMP;
--関数の宣言
/**************************************************************************
* 関数名:f_getEname
* 説明 :従業員名を取得する
* PARAM(IN ) :iEmpno 従業員番号
* RETURN :従業員名
**************************************************************************/
FUNCTION f_getEname (
iEmpno IN EMP.EMPNO%TYPE
) RETURN EMP.ENAME%TYPE IS
--関数の宣言部
wk_ename EMP.ENAME%TYPE; --戻り値
BEGIN
SELECT
ENAME INTO wk_ename
FROM EMP
WHERE
EMPNO = iEmpno;
RETURN wk_ename;
EXCEPTION
WHEN NO_DATA_FOUND THEN
wk_ename := 'NO DATA';
RETURN wk_ename;
WHEN TOO_MANY_ROWS THEN
wk_ename := 'ERROR';
RETURN wk_ename;
END f_getEname;
--プロシージャの宣言
/**************************************************************************
* 関数名:p_getEname
* 説明 :従業員名を取得する
* PARAM(IN) :iEmpno 従業員番号
* PARAM(OT) :oEName 従業員名
**************************************************************************/
PROCEDURE p_getEname(
iEmpno IN EMP.EMPNO%TYPE
,oEname OUT EMP.ENAME%TYPE
) IS
--宣言部
BEGIN
SELECT
ENAME INTO oEname
FROM EMP
WHERE
EMPNO = iEmpno;
EXCEPTION
WHEN NO_DATA_FOUND THEN
oEname := 'NO DATA';
WHEN TOO_MANY_ROWS THEN
oEname := 'ERROR';
END p_getEname;
BEGIN
--ファンクションの呼び出し
FOR q01Record IN q01Selector LOOP
wk_ename := f_getEname(q01Record.EMPNO);
DBMS_OUTPUT.PUT_LINE(wk_ename);
END LOOP;
--プロシージャの呼び出し
FOR q01Record IN q01Selector LOOP
p_getEname(q01Record.EMPNO, wk_ename);
DBMS_OUTPUT.PUT_LINE(wk_ename);
END LOOP;
END;
コメント