内部関数が足りない? それならUDFだ!
アナハイムテクノロジー
はやしつとむ
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 |
- Oracleライセンス「SE2」検証 CPUスレッド数制限はどんな仕組みで制御されるのか (2017/7/26)
データベース管理システムの運用でトラブルが発生したらどうするか。DBサポートスペシャリストが現場目線の解決Tipsをお届けします。今回は、Oracle SE2の「CPUスレッド数制限」がどんな仕組みで行われるのかを検証します - ドメイン参加後、SQL Serverが起動しなくなった (2017/7/24)
本連載では、「SQL Server」で発生するトラブルを「どんな方法で」「どのように」解決していくか、正しい対処のためのノウハウを紹介します。今回は、「ドメイン参加後にSQL Serverが起動しなくなった場合の対処方法」を解説します - さらに高度なSQL実行計画の取得」のために理解しておくべきこと (2017/7/21)
日本オラクルのデータベーススペシャリストが「DBAがすぐ実践できる即効テクニック」を紹介する本連載。今回は「より高度なSQL実行計画を取得するために、理解しておいてほしいこと」を解説します - データベースセキュリティが「各種ガイドライン」に記載され始めている事実 (2017/7/20)
本連載では、「データベースセキュリティに必要な対策」を学び、DBMSでの「具体的な実装方法」や「Tips」などを紹介していきます。今回は、「各種ガイドラインが示すコンプライアンス要件に、データベースのセキュリティはどのように記載されているのか」を解説します
|
|