CREATE FUNCTION

CREATE FUNCTION文は、スタンドアロンのストアド・ファンクションを作成します。

必要な権限

CREATE PROCEDURE(所有者の場合)またはCREATE ANY PROCEDURE(非所有者の場合)。

TimesTen Scaleoutでの使用

この文は、TimesTen Scaleoutでサポートされています。

SQL構文

CREATE [OR REPLACE] FUNCTION [Owner.]FunctionName 
     [(arguments [IN|OUT|IN OUT][NOCOPY] DataType [DEFAULT expr][,...])]
     RETURN DataType 
     [InvokerRightsClause][AccessibleByClause][DETERMINISTIC]
     {IS|AS} PlsqlFunctionBody

InvokerRightsClause::=
AUTHID {CURRENT_USER|DEFINER}

AccessibleByClause::=
ACCESSIBLE BY (accessor[,...])

accessor::= 
[UnitKind][Owner.]UnitName

InvokerRightsClauseAccessibleByClauseまたはDETERMINISTICは任意の順序で指定できます。

パラメータ

パラメータ 説明

OR REPLACE

ファンクションがすでに存在する場合に再作成するには、OR REPLACEを指定します。この句を使用して、削除および再作成せずに既存のファンクションの定義を変更します。ファンクションを再作成すると、そのファンクションはTimesTenで再コンパイルされます。

FunctionName

ファンクションの名前。

arguments

引数またはパラメータの名前。ファンクションに0以上のパラメータを指定できます。パラメータを指定する場合は、パラメータのデータ型を指定する必要があります。データ型はPL/SQLデータ型である必要があります。

IN|OUT|IN OUT

パラメータのモード。

INは読取り専用パラメータです。パラメータの値をファンクションに渡すことはできますが、ファンクションはパラメータの値をファンクション外に渡したり、コール側PL/SQLブロックに戻したりすることはできません。パラメータの値は変更できません。

OUTは書込み専用パラメータです。値をファンクションからコール側PL/SQLブロックに戻すには、OUTパラメータを使用します。パラメータに値を割り当てることができます。

IN OUTは読取り/書込みパラメータです。値をファンクションに渡し、コール側プログラムに戻すことができます(元の変更されていない値またはファンクション内で設定された新しい値)。

INがデフォルトです。

NOCOPY

可能なかぎり迅速にパラメータを渡すようにTimesTenに指示するには、NOCOPYを指定します。レコード、索引付き表、OUTまたはIN OUTパラメータへのVARRAYなどの大きな値を渡す場合に、パフォーマンスを向上できます。INパラメータでは、常にNOCOPYが渡されます。

DEFAULT expr

パラメータのデフォルト値を指定するには、この句を使用します。キーワードDEFAULTのかわりに:=を指定できます。

RETURN DataType

必須の句。ファンクションは値を戻す必要があります。ファンクションの戻り値のデータ型を指定する必要があります。

データ型の長さ、精度またはスケールは指定しないでください。

データ型はPL/SQLデータ型です。

InvokerRightsClause

PL/SQLファンクションまたはプロシージャ内のSQL文が定義者権限で実行されるか実行者権限で実行されるかを指定できます。AUTHIDの設定は、実行時にPL/SQLプロシージャまたはファンクションによって発行されるSQL文の名前解決および権限チェックに次のように影響を与えます。

  • DEFINERを指定すると、SQLの名前解決および権限チェックは、プロシージャまたはファンクションの所有者(定義者、つまりプロシージャまたはファンクションがあるスキーマの所有者)が実行しているものとして実行されます。DEFINERがデフォルトです。

  • CURRENT_USERを指定すると、SQLの名前解決および権限チェックは、現在のユーザー(実行者)が実行しているものとして実行されます。

詳細は、『Oracle TimesTen In-Memory Databaseセキュリティ・ガイド』「定義者権限および実行者権限(AUTHID句)」を参照してください。

AccessibleByClause

この句は、ファンクションを直接呼び出せる1つ以上のアクセッサ(PL/SQLユニット)を指定する場合に使用します。ファンクションにアクセスできるアクセッサのリストは、ホワイトリストと呼ばれます。ホワイト・リストを使用すると、PL/SQLオブジェクトにセキュリティ・レイヤーを追加できます。特に、ホワイト・リストにあるオブジェクトのみにファンクションへのアクセスを制限できます。

AccessibleByClauseは、CREATE FUNCTION文で1回のみ指定できます。

構文: ACCESSIBLE BY (accessor [,...])

accessor

AccessibleByClauseで使用されます。アクセッサは、ファンクションを呼び出せるPL/SQLユニットです。

アクセッサは、AccessibleByClause句で複数回指定できます。

構文: [UnitKind][Owner.]UnitName

UnitKind

accessor句(AccessibleByClause句の一部)で使用されます。ファンクションを呼び出せるPL/SQLユニットの種類を指定します。

  • UnitKindはオプションですが、指定する場合の有効なオプションは次のとおりです。
  • FUNCTION

  • PROCEDURE

  • PACKAGE

[Owner.]UnitName

accessor句(AccessibleByClause句の一部)で使用されます。ファンクションを呼び出せるPL/SQLユニットの名前を指定します。UnitKindを指定する場合、UnitNameをこの種類のユニットの名前にする必要があります。たとえば、UnitKindPROCEDUREを指定する場合、UnitNameはプロシージャ名である必要があります。UnitNameは必須です。

Ownerは必要に応じて指定できます。Ownerを指定する場合、UnitNameがその所有者のスキーマ内に常駐する必要があります。Ownerを指定しない場合、UnitNameは関数を含むスキーマ内にある必要があります。

DETERMINISTIC

パラメータに同じ値を指定して関数をコールした場合に常に同じ結果値を返すように指定するには、DETERMINISTICを指定します。

IS|AS

ISまたはASを指定して、ファンクションの本体を宣言します。

plsql_function_spec

ファンクションの本体を指定します。

説明

  • AccessibleByClause:

    • コンパイラはACCESSIBLE BY句の構文の妥当性をチェックしますが、アクセッサが存在することはチェックしません。このため、所有者のスキーマにまだ存在しているアクセッサを定義できます。

    • ファンクションを呼び出すと、コンパイラはまず呼出しの通常のアクセス権チェックを実行します。いずれかのチェックに失敗すると、呼出し元がアクセッサであっても呼出しは失敗します。呼出し時の通常のアクセス権チェックがすべて成功し、このファンクションにACCESSIBLE BY句がない場合、呼出しは成功します。ファンクションにACCESSIBLE BY句がある場合、呼出し元がアクセッサである場合にのみ呼出しは成功します。

  • ファンクションを作成または置き換えた場合、ファンクションに付与された権限は同じままです。オブジェクトを削除して再作成した場合、元のオブジェクトに付与されていたオブジェクト権限は削除されます。

  • レプリケーション環境で、CREATE FUNCTION文はレプリケートされません。詳細は、『Oracle TimesTen In-Memory Databaseレプリケーション・ガイド』「既存のアクティブ・スタンバイ・ペアでの新しいPL/SQLオブジェクトの作成」および「既存のクラシック・レプリケーション・スキームへのPL/SQLオブジェクトの追加」を参照してください。

  • 次の句はTimesTenではサポートされません。

    • parallel_enable_clause

      句を指定できますが、無効になります。

    • call_spec

    • AS EXTERNAL

Accessible By句の使用

この例では、ProtectedFunction関数を作成します。ACCESSIBLE BY句は、ファンクションの呼出しをCallingProc1プロシージャおよびCallingProc2プロシージャに制限するために使用されます。CallingProc1ではPL/SQLユニットのタイプは指定されず、CallingProc2では、PL/SQLユニットのタイプは(PROCEDURE)と指定されることに注意してください。

Command> CREATE OR REPLACE FUNCTION ProtectedFunction (a IN NUMBER)
           RETURN NUMBER
         ACCESSIBLE BY (CallingProc1, PROCEDURE CallingProc2)
         AS
         BEGIN
           RETURN a * 1;
         END;
         /
         
Function created.

CallingProc1プロシージャとCallingProc2プロシージャを作成します。

Command> CREATE OR REPLACE PROCEDURE CallingProc1 AS
           a NUMBER:=1;
         BEGIN
           a:=ProtectedFunction(a);
           DBMS_OUTPUT.PUT_LINE ('Calling Procedure: '|| a);
         END;
         /
         
Procedure created.

Command> CREATE OR REPLACE PROCEDURE CallingProc2
         AS
           a NUMBER:=2;
         BEGIN
           a:=ProtectedFunction(a);
           DBMS_OUTPUT.PUT_LINE ('Calling Procedure: '|| a);
         END;
         /
         
Procedure created.

プロシージャをコールします。CallingProc1およびCallingProc2はホワイト・リストにあり、実行は成功します。

Command> SET SERVEROUTPUT ON
Command> exec CallingProc1;
Calling Procedure: 1
 
PL/SQL procedure successfully completed.
 
Command> exec CallingProc2;
Calling Procedure: 2
 
PL/SQL procedure successfully completed.

PL/SQLファンクションを作成するための構文の説明

1つの入力パラメータを指定してファンクションget_salを作成します。NUMBER型としてsalaryを戻します。

Command> CREATE OR REPLACE FUNCTION get_sal
           (p_id employees.employee_id%TYPE) RETURN NUMBER IS
           v_sal employees.salary%TYPE := 0;
         BEGIN
           SELECT salary INTO v_sal FROM employees
             WHERE employee_id = p_id;
           RETURN v_sal;
         END get_sal;
         /
 
Function created.