e-learning、オラクル研修、LMS(学習管理システム)のiStudy

e-learning、オラクル研修、LMS(学習管理システム)のiStudy

第22回 「ストアド・ファンクション作成構文」

2012.05.28

前回はストアド・ファンクションの概要について解説しました。
ファンクションは、値を返す点とコールの仕方がプロシージャと大きく違うということでしたね。

今回からはスアド・ファンクションの文法について解説します。

まずはストアド・ファンクションの作成構文ですが、プロシージャの作成構文(本メルマガ第17回)とそれほど変わりません。

プロシージャとの違いを中心に説明します。

<<ストアド・ファンクションの作成構文 >>
1 CERATE OR REPLACE FUNCTION ファンクション名 (仮パラメータ名  モード データ型, ・・・・)
2 RETURNN データ型
3 IS
4   宣言部
5 BEGIN
6   実行部
7   RETURN 値;
8 EXCEPTION
9   例外処理部
10 END;

では、プロシージャとの違いを解説します。

●ファンクション作成のキーワード(1行目)は「PROCEDURE」ではなく「FUNCTION」である。
当たり前ではありますが、CREATE OR REPLACEで、キーワード 「FUNCTION」を指定します。

●仮パラメータモード(1行目)は「IN」だけを使用する。
仮パラメータのモードは、「IN」を使用します。
正確に言うと他のモード(「OUT」、「IN OUT」)も使用可能ではあるのですが、そのような使い方は世間一般ではしておらず、混乱をきたしますので、慣例として「IN」だけを使用します。

●リターンするデータ型が必要(2行目)
そのファンクションが返す値のデータ型を「IS」の前に指定します。(RETURN データ型)
このデータ型は、仮パラメータのデータ型と同じく、サイズは指定できません。
仮パラメータもRETURNするデータ型も、呼び出し元との間の値のやり取りに使われますので、サイズは限定できないわけです。
(例)
   RETURN  VARCHAR2(10) → コンパイルエラー
   RETURN  VARCHAR2 → OK

※ %TYPEや、%ROWTYPEの指定も仮パラメータと同様に可能です。

●実行部の最後は、RETURN文である。(7行目)
ファンクションは、値を返す(RETURNする)ことで、実行を終了します。
たとえ、RETURN処理の後に何かの処理が記述されていても、それは実行されないので注意してください。
値を返す(RETURNする)ことで役目を終えるわけです。値を返す(RETURNする)処理は必須です。

では具体的な事例として、本メルマガ第20回で解説した発番処理のプロシージャをファンクションにしたものを以下に掲載します。
プロシージャと違う点を右側にコメントしました。

SQL> L
  1  CREATE OR REPLACE FUNCTION FUNC_順序番号    --←キーワードはFUNCTION
  2         (P_発番単位 IN  VARCHAR2)            --←仮パラメータのモードは INだけ
  3  RETURN NUMBER                              --←RETURNするデータ型を宣言する
  4  IS
  5      V_発番済番号 順序.番号%TYPE;
  6      V_番号 NUMBER;
  7  BEGIN
  8                                -- 指定された発番単位を1足しこみ変数に格納する
  9         UPDATE 順序
10         SET 番号 = 番号 + 1
11         WHERE 発番単位 = P_発番単位
12         RETURNING 番号 INTO V_番号;

13                                    -- その変数の値をRETURNする
14         RETURN   V_番
号;                     --← 値をリターンして終了する
15* END;
SQL> /

ファンクションが作成されました。

内容を簡単に説明すると、このファンクションは順序表の指定された発番単位の番号を1足しこんでその値を返す単純なものです。

たとえば、発番単位「注文ID」の現在の番号は3番です。
以下の問い合わせをご覧ください。

SQL> select * from 順序 where 発番単位 = '注文ID';

発番単位                   番号
------------------------------
注文ID                        3

ここで、この状態で発番単位に「注文ID」を指定してこのファンクションを4回コールし、dbms_output.put_lineで画面表示します。
ファンクションのコールはそれ自体が値なので、dbms_outputl.put_lineの引数として記述できます。
そうすると、3番以降の値が4,5,6,7と返されるはずです。

やってみましょう。

SQL> ed
file afiedt.bufが書き込まれました。

  1  begin
  2     dbms_output.put_line(FUNC_順序番号('注文ID'));
  3     dbms_output.put_line(FUNC_順序番号('注文ID'));
  4     dbms_output.put_line(FUNC_順序番号('注文ID'));
  5     dbms_output.put_line(FUNC_順序番号('注文ID'));
  6* end;
SQL> /
4        ←FUNC_順序ファンクションが返した値
5        ←FUNC_順序ファンクションが返した値
6        ←FUNC_順序ファンクションが返した値
7        ←FUNC_順序ファンクションが返した値

PL/SQLプロシージャが正常に完了しました。

確かに、3番以降の番号が、4,5,6,7と発番されたことがわかります。

では、確認はここまでにします。
後始末として、このファンクションは、順序表を更新しましたのでrollbackしておきます。

SQL> rollback;

ロールバックが完了しました。

それでは、今回はここまでです。
次回は、ファンクションの詳細を解説します。
ご期待ください。

先頭へ戻る