Yet another OSS DB:Firebird(5)

内部関数が足りない? それならUDFだ!

Firebird日本ユーザー会
アナハイムテクノロジー
はやしつとむ
2009/6/9

引数を取らないUDF

 では、Delphiで乱数を返すUDFを書いてみましょう。

 Delphiの場合はrandom関数に引数を与えずに呼び出すと、0≦X<1の範囲で値を返します。つまり、[0,1)の左半開区間になります。ちなみに、Firebird/PostgreSQL/DB2の乱数は標準では[0,1]の閉区間となっていますが、Oracle/MySQLでは左半開区間になっています。SQLサーバだけは(0,1)で両端を含まない開区間です。

library UDF_sample;


uses
  SysUtils, Classes, Windows;


{$R *.res}


function tomneko_rand:double;stdcall;
begin
  result := random();
end;


exports
  tomneko_rand;


begin
end.

 一見して非常に単純であることが分かります。パラメータを受け取らず、戻り値が数値型のUDFは上記のような書き方をします。呼び出し規約は、InterBase6以降ではstdcallを使うように指定されています。

 作成したUDFは、“データベースごと”に登録しないと使用することができません。“サーバごと”ではないので注意してください。登録用スクリプトは以下のようになります。

/* function tomneko_rand: double; 
*/

DECLARE EXTERNAL FUNCTION TOMNEKO_RAND
  RETURNS DOUBLE PRECISION BY VALUE
  ENTRY_POINT 'tomneko_rand'  MODULE_NAME 'UDF_sample';

数値型の引数を取るUDF

 次に、UDFに引数を渡すための方法を検討します。まず、Firebirdでは、UDFに10個までの引数を渡すことができます。ただし、配列要素は引数として渡すことはできません。BLOB型については、後ほど検討します。

 プログラミング言語での引数のデータ型と、Firebirdのデータ型とは一致しなくても構いませんが、Fierbirdが取り扱える形式でなくてはなりません。例えば、先ほどのtomneko_rand()関数は、DelphiではDouble型ですが、Firebirdでは自動的にDOUBLE PRECISION型に変換されます。

 UDFの戻り値については、デフォルトでは参照渡しで返されますが、数値型については値渡しを指定することも可能です。その場合は、DECLARE EXTERNAL FUNCTION文でBY VALUEキーワードを指定します。また、戻り値の指定でRETURNS PARAMETER nを利用することで、Firebirdの管理するメモリ領域を利用して戻り値を返すことが可能です。この点についても、後ほど検討します。

 さて、UDFに引数を渡すコードを見てみましょう。同じくIB_UDFのソースコードからです。

ib_udf.cpp(59)
double EXPORT IB_UDF_abs( double *a)
{
	return (*a < 0.0) ? -*a : *a;
}

 これも大変単純な関数ですが、IB_UDF_abs()関数は、引数の絶対値を返します。引数はdouble型のポインタaとして宣言されています。三項演算子を使用して、引数が0.0より小さければ-aを、そうでなければaをそのまま返します。

 同じUDFをDelphiで作成すると以下のようになります。

function tomneko_abs(var a:double):double;stdcall;
begin
result := abs(a);
end;

●登録用スクリプト:

/*  External Function declarations */

DECLARE EXTERNAL FUNCTION TOMNEKO_ABS
DOUBLE PRECISION
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'tomneko_abs' MODULE_NAME 'UDF_sample';

●使用例:

SQL> SELECT TOMNEKO_ABS(-3) FROM RDB$DATABASE;
            TOMNEKO_ABS
=======================
      3.000000000000000
前のページへ 2/4 次のページへ

Index
内部関数が足りない? それならUDFだ!

Page 1
内部関数で物足りないあなたに
UDFの仕組み
標準UDFのコード
→ Page 2
引数を取らないUDF
数値型の引数を取るUDF

Page 3
UDFに文字を渡す
UDFに文字列を渡す

Page 4
最後に
Yet another OSS DB:Firebird


Database Expert フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Database Expert 記事ランキング

本日月間