アプリケーション開発の手引き


関数とメソッドの使用法

スカラー UDF / メソッドと列 UDF / メソッドは、式が有効な場所 (すべての列関数について、有効性を制限する追加の規則があります) であれば、 SQL ステートメント内のどこでも呼び出せます。表 UDF を参照できるのは、SELECT の FROM 文節内だけです。 SQL 解説書 では、これらのすべての文脈について詳しく説明しています。なお、この節では比較的単純な SELECT ステートメントの文脈に重点を置いて例を挙げて説明していますが、これらはこの文脈以外でも使用できます。

使用法の概要、 関数パス の重要性、および関数選択 のアルゴリズムについては、 UDF とメソッドの概念を参照してください。これらの概念は両方とも、 SQL 解説書 で詳しく説明されています。関数に対するデータ操作言語 (DML) 参照の分析には、関数選択のアルゴリズムを使用するので、これがどのように作用するのかを理解しておくことが重要です。

関数の参照

各関数の参照には、UDF または組み込み関数のいずれの場合も次の構文が含まれています。

>>-function_name--(--+--------------------+---)----------------><
                     |  .-,------------.  |
                     |  V              |  |
                     '----expression---+--'
 

上記の例で、 function_name は、修飾された関数名かまたは修飾されない関数名のいずれかで、引き数は 0 〜 90 までの値となります。また、式に以下のものが含まれます。

引き数の位置は重要で、それを意味する関数の定義に正確に従っていなければなりません。引き数の位置と、関数の定義の両方が関数本体に従っていなければなりません。 DB2 は、引き数が関数の定義とうまく一致するように、引き数を入れ替えたりはしません。また、DB2 はそれぞれの関数パラメーターの意味を認識しません。

UDF 引き数式で列名を使用するには、その列を含む列参照が適切な効力範囲を持つことが必要です。結合で参照される表関数では、引き数が他の表や表関数にある列と関係している場合、その表や表関数は、参照を含む表関数の前に、FROM 文節で示されていなければならない、ということを意味します。表関数の引き数で列を使用する際の規則の詳細については、 SQL 解説書 を参照してください。

関数呼び出しの例

以下に、関数呼び出しの正しい例を示します。

      AVG(FLOAT_COLUMN)
      BLOOP(COLUMN1)
      BLOOP(FLOAT_COLUMN + CAST(? AS INTEGER))
      BLOOP(:hostvar :indicvar)
      BRIAN.PARSE(CHAR_COLUMN CONCAT USER, 1, 0, 0, 1)
      CTR()
      FLOOR(FLOAT_COLUMN)
      PABLO.BLOOP(A+B)
      PABLO.BLOOP(:hostvar)
      "search_schema"(CURRENT FUNCTION PATH, 'GENE')
      SUBSTR(COLUMN2,8,3)
      SYSFUN.FLOOR(AVG(EMP.SALARY))
      SYSFUN.AVG(SYSFUN.FLOOR(EMP.SALARY))
      SYSIBM.SUBSTR(COLUMN2,11,LENGTH(COLUMN3))
      SQRT(SELECT SUM(length*length)
           FROM triangles
           WHERE id= 'J522'
           AND legtype <> 'HYP')

上記の関数のいずれかが表関数である場合、それらの関数を参照する構文は、上記の関数とはわずかに異なっています。たとえば PABLO.BLOOP が表関数であれば、次のようにしてこの関数を正しく参照します。

     TABLE(PABLO.BLOOP(A+B)) AS Q

関数でのパラメーター・マーカーの使用法

重要な制限事項には、パラメーター・マーカーが関係しています。単に次のようにコード化するだけでは不十分です。

     BLOOP(?)

関数選択のロジックでは引き数がどのデータ・タイプになるのか分からないので、これにより参照を分析することはできません。 CAST という指定を使用して、パラメーター・マーカーにタイプを指定できます。たとえば INTEGER とすると、関数選択のロジックは次の処理を進めることができます。

     BLOOP(CAST(? AS INTEGER))

修飾された関数参照の使用法

修飾された関数参照を使用する場合、 DB2 がそのスキーマに一致する関数のみを検索するようにします。たとえば、次のようなステートメントになります。

     SELECT PABLO.BLOOP(COLUMN1) FROM T

これで PABLO というスキーマの BLOOP 関数のみが考慮されます。このとき、SERGE というユーザーが BLOOP 関数を定義したことや、 BLOOP 組み込み関数の有無は問題になりません。たとえば、PABLO というユーザーがご使用のスキーマで次の 2 つの BLOOP 関数を定義したとします。

     CREATE FUNCTION BLOOP (INTEGER) RETURNS ...
     CREATE FUNCTION BLOOP (DOUBLE) RETURNS ...

このようにして BLOOP は PABLO スキーマ内で多重定義され、最適な BLOOP が、関数選択アルゴリズムにより引き数 COLUMN1 のデータ・タイプに従って選択されます。この場合、いずれの PABLO.BLOOP も数値引き数を取り、 COLUMN1 がいずれかの数値タイプでないならばそのステートメントは実行できません。一方 COLUMN1 が SMALLINT または INTEGER のいずれかである場合は、関数選択は最初の BLOOP に変換されますが、 COLUMN1 が DECIMAL、DOUBLE、REAL、または BIGINT ならば 2 番目の BLOOP が選択されます。

以下に、この例のポイントを挙げます。

  1. この例は、引き数のプロモーションを示しています。最初の BLOOP は、INTEGER パラメーターによって定義されますが、 SMALLINT 引き数に渡すことができます。関数選択アルゴリズムは、組み込みデータ・タイプ (詳細については、 SQL 解説書 を参照) 間のプロモーションをサポートし、 DB2 は、データ値の変換を適切に行います。
  2. 何らかの理由のために SMALLINT または INTEGER 引き数を指定した 2 番目の BLOOP を呼び出したい場合は、ご使用のステートメント内で以下のようなアクションを明示的に実行しなければなりません。
         SELECT PABLO.BLOOP(DOUBLE(COLUMN1)) FROM T
    
  3. 代わりに DECIMAL または DOUBLE 引き数を指定した最初の BLOOP を呼び出したい場合は、厳密な目的の下で以下のアクションのうちのどちらかを選んで実行します。
         SELECT PABLO.BLOOP(INTEGER(COLUMN1)) FROM T
         SELECT PABLO.BLOOP(FLOOR(COLUMN1)) FROM T
         SELECT PABLO.BLOOP(CEILING(COLUMN1)) FROM T
         SELECT PABLO.BLOOP(INTEGER(ROUND(COLUMN1,0))) FROM T
    

    その他の関数については、 SQL 解説書 を参照してください。 INTEGER 関数は、SYSIBM というスキーマの組み込み関数です。 FLOOR、CEILING、および ROUND 関数は、DB2 と共に出荷される UDF で、これらは他の多くの便利な関数と共に SYSFUN スキーマ中にあります。

修飾されない関数参照の使用法

一致する関数を検索する場合に、修飾された関数参照の代わりに修飾されない関数参照を使用すると、 DB2 は関数パスを使用して参照を修飾します。 DROP FUNCTION または COMMENT ON FUNCTION 関数の場合、それらが修飾されないものであれば、その参照は現行の許可 ID を使用して修飾されます。このため、使用する関数パスが何であるか、またご使用の現行関数パスのスキーマに矛盾したパスがある場合はそれがどのようなものであるかを知っておくことが重要です。 たとえば、ユーザーが PABLO で、ユーザーの静的 SQL ステートメントが次のようになっているとします。ここで、COLUMN1 のデータ・タイプは INTEGER です。

     SELECT BLOOP(COLUMN1) FROM T

そして、修飾された関数参照の使用法で例証されている 2 つの BLOOP 関数を作成しており、それらのうちいずれか 1 つを選択したいとします。次の省略時の関数パスが使用された場合、 SYSIBM または SYSFUN に矛盾する BLOOP がないと、 (COLUMN1 が INTEGER であるので) 最初の BLOOP 関数が選択されます。

     "SYSIBM","SYSFUN","PABLO"

しかし、前に別の目的で作成したスクリプトを、コンパイルおよびバインドを行うために使用しているということを忘れていたとします。そのスクリプトでは、FUNCPATH パラメーターを明示的にコーディングして、現行の作業に適用されない以下の関数パスを別の理由で指定しました。

     "KATHY","SYSIBM","SYSFUN","PABLO"

Kathy が自分専用に BLOOP 関数を定義していた場合は、関数選択は Kathy の関数を首尾よく解決でき、ユーザーのステートメントはエラーを起こさずに実行される。 DB2 は、ユーザーが自分自身の行っていることを理解しているとみなすので、ユーザーには通知しません。ユーザーは、ステートメントからの誤った出力を識別し、要求される修正を行うことについて責任を負うことになります。

関数参照の要約

修飾された、および修飾されない関数参照のいずれの場合も、関数選択のアルゴリズムは適当な関数、つまり組み込みおよびユーザー定義関数の両方を調べます。これらの関数は以下のものを伴います。

(上記の説明中の適当な関数 とは、修飾された参照の場合は名前の付いたスキーマの関数、修飾されない参照の場合は関数パスのスキーマの関数 を意味します。) アルゴリズムにより正確に一致するものが検索されますが、一致するものが見つからなかった場合は、これらの関数のうちで最適なものが検索されます。修飾されない参照の場合のみ、異なるスキーマでまったく同じものが 2 つ検出されると、判別要素として現行の関数パスが使用されます。このアルゴリズムについては、SQL 解説書 で詳しく説明されています。

修飾された関数参照の使用法の最後に引用されている機能は、同じ関数に対する参照の場合でも関数参照をネストできる という注目すべきものです。このことは通常、UDF の他に、組み込み関数についても言えますが、列関数が含まれる場合はいくつかの制限があります。

非常に簡単な例を示します。

     CREATE FUNCTION BLOOP (INTEGER) RETURNS INTEGER ...
     CREATE FUNCTION BLOOP (DOUBLE) RETURNS INTEGER ...

ここで次の DML ステートメントについて考えます。

     SELECT BLOOP( BLOOP(COLUMN1)) FROM T

COLUMN1 が DECIMAL または DOUBLE 列である場合は、内部の BLOOP 参照は、上で定義されている 2 番目の BLOOP に変換されます。この BLOOP は INTEGER を戻すので、外部の BLOOP は最初の BLOOP に変換されます。

また、COLUMN1 が SMALLINT または INTEGER 列である場合は、内部の BLOOP 参照は、上で定義されている最初の BLOOP に変換されます。この BLOOP は INTEGER を戻すので、外部の BLOOP も最初の BLOOP に変換されます。この場合、同じ関数に対してネストされた参照を見ていることになります。

関数参照についてさらに重要なポイントを以下に示します。


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]