ネイティブ関数または外部関数へのインタフェースを作成します。
CREATE [ OR REPLACE ] FUNCTION [ owner.]function-name ( [ parameter, ... ] ) [ SQL SECURITY { INVOKER | DEFINER } ] RETURNS data-type [ [ NOT ] DETERMINISTIC ] { EXTERNAL NAME 'native-call' | EXTERNAL NAME 'c-call' LANGUAGE { C_ESQL32 | C_ESQL64 | C_ODBC32 | C_ODBC64 } | EXTERNAL NAME 'clr-call' LANGUAGE CLR | EXTERNAL NAME 'perl-call' LANGUAGE PERL | EXTERNAL NAME 'php-call' LANGUAGE PHP | EXTERNAL NAME 'java-call' LANGUAGE JAVA }
parameter : [ IN ] parameter-name data-type [ DEFAULT expression ]
native-call : [ operating-system:]function-name@library
result-column : column-name data-type
c-call : [ operating-system:]function-name@library; ...
clr-call : dll-name::function-name( param-type-1[, ... ] )
perl-call : <file=perl-file> $sa_perl_return = perl-subroutine( $sa_perl_arg0[, ... ] )
php-call : <file=php-file> print php-func( $argv[1][, ... ] )
java-call : [package-name.]class-name.method-name method-signature
operating-system :
Unix
method-signature : ( [ field-descriptor, ... ] ) return-descriptor
field-descriptor と return-descriptor: { Z | B | S | I | J | F | D | C | V | [descriptor | Lclass-name; }
パラメータ名は、データベース識別子に対するルールに従って付けてください。パラメータ名は、有効な SQL データ型にします。また、キーワード IN のプレフィクスを付けて、引数が関数に値を提供する式であることを示してください。ただし、関数パラメータはデフォルトで IN です。
関数を実行するときに、すべてのパラメータを指定する必要はありません。CREATE FUNCTION 文の中に DEFAULT 値がある場合、不明のパラメータにデフォルト値を割り当てます。呼び出すときに引数を指定せず、デフォルトも設定されていない場合には、エラーが発生します。
OR REPLACE 句 OR REPLACE を指定すると、新しい関数が作成されるか、同じ名前の既存の関数が置き換えられます。この句によって、関数の定義は変更されますが、既存の権限は保持されます。OR REPLACE 句をテンポラリ関数で使用することはできません。
RETURNS 句 RETURNS 句は、関数の結果のデータ型を指定するときに使用します。
SQL SECURITY 句 SQL SECURITY 句は、INVOKER (関数を呼び出すユーザ) または DEFINER (関数を所有するユーザ) として関数が実行されるかどうかを定義します。デフォルトは DEFINER です。外部呼び出しの場合、この句は、外部環境での修飾されていないオブジェクト参照に対して所有者のコンテキストを確立します。
SQL SECURITY INVOKER が指定されている場合、関数を呼び出すユーザごとに注釈を行う必要があるため、メモリ使用量が増えます。また、SQL SECURITY INVOKER が指定されている場合は、呼び出し側としても名前の決定が行われます。このため、すべてのオブジェクト名 (テーブル、プロシージャなど) を該当する所有者で修飾する場合は注意が必要です。たとえば、user1 が次の関数を作成するとします。
CREATE FUNCTION user1.myFunc() RETURNS INT SQL SECURITY INVOKER BEGIN DECLARE res INT; SELECT COUNT(*) INTO res FROM table1; RETURN res; END; |
user2 がこの関数を実行しようとし、テーブル user2.table1 が存在しない場合、テーブルルックアップエラーが生じます。さらに、user2.table1 が存在する場合は、意図する user1.table1 の代わりにこのテーブルが使用されます。このような状況を防ぐには、文においてテーブル参照を修飾します (単なる table1 ではなく、user1.table1 とします)。
[ NOT ] DETERMINISTIC 句 この句は、関数が決定的か非決定的かを示すために使用します。この句が省略されると、関数の決定的な動作は指定されません (デフォルト)。
DETERMINISTIC と宣言された関数は、同じパラメータセットで呼び出されるたび、同じ値を返します。
NOT DETERMINISTIC と宣言された関数は、同じパラメータセットに対して同じ値を返すとはかぎりません。NOT DETERMINISTIC として宣言された関数は、クエリで呼び出されるたびに再評価されます。特定のパラメータセットに対して関数が返す結果が変化するとわかっている場合は、この句を使用してください。
また、基本となるデータの修正などの関連する動作を伴う関数は、NOT DETERMINISTIC として宣言してください。たとえば、プライマリキー値を生成し、INSERT...SELECT 文で使用する関数は、次のように NOT DETERMINISTIC として宣言してください。
CREATE FUNCTION keygen( increment INTEGER ) RETURNS INTEGER NOT DETERMINISTIC BEGIN DECLARE keyval INTEGER; UPDATE counter SET x = x + increment; SELECT counter.x INTO keyval FROM counter; RETURN keyval END INSERT INTO new_table SELECT keygen(1), ... FROM old_table; |
特定の入力パラメータに対して常に同じ値を返す関数は、DETERMINISTIC として宣言できます。
native-call : [operating-system:]function-name@library; ...
operating-system : Unix
EXTERNAL NAME 句は TEMPORARY 関数ではサポートされていませんので、注意してください。
library 名にはファイル拡張子を付けることができます。これは通常、Windows では .dll、UNIX では .so です。拡張子がない場合、ライブラリに対するプラットフォーム固有のデフォルトのファイル拡張子が追加されます。次に例を示します。
CREATE FUNCTION mystring( IN instr LONG VARCHAR ) RETURNS LONG VARCHAR EXTERNAL NAME 'mystring@mylib.dll;Unix:mystring@mylib.so'; |
上記の EXTERNAL NAME 句を、プラットフォーム固有のデフォルト値を使用して簡単に記述すると、次のようになります。
CREATE FUNCTION mystring( IN instr LONG VARCHAR ) RETURNS LONG VARCHAR EXTERNAL NAME 'mystring@mylib'; |
呼び出されると、関数を含むライブラリがデータベースサーバのアドレス領域にロードされます。ネイティブ関数は、サーバの一部として実行されます。この場合、関数が原因で障害が発生すると、データベースサーバは終了されます。したがって、外部環境での関数のロードと実行には、LANGUAGE 属性を使用することをおすすめします。関数が原因で外部環境に障害が発生しても、データベースサーバは実行し続けます。
EXTERNAL NAME c-call LANGUAGE {C_ESQL32 | C_ESQL64 | C_ODBC32 | C_ODBC64 } 句 コンパイル済みネイティブ C 関数をデータベースサーバ内でなく外部環境で呼び出すには、ストアドプロシージャまたはファンクションを EXTERNAL NAME 句で定義し、後続の LANGUAGE 属性で C_ESQL32、C_ESQL64、C_ODBC32、C_ODBC64 のいずれか 1 つを指定します。
LANGUAGE 属性が指定されると、その関数を含むライブラリが外部プロセスによってロードされ、外部関数がその外部プロセスの一部として実行されます。この場合、関数が原因で障害が発生しても、データベースサーバは実行し続けます。
CREATE FUNCTION ODBCinsert( IN ProductName CHAR(30), IN ProductDescription CHAR(50) ) RETURNS INT EXTERNAL NAME 'ODBCexternalInsert@extodbc.dll' LANGUAGE C_ODBC32; |
EXTERNAL NAME clr-call LANGUAGE CLR 句 .NET 関数を外部環境で呼び出すには、関数インタフェースを EXTERNAL NAME 句で定義し、それに続いて LANGUAGE CLR 属性を指定します。
CLR ストアドプロシージャまたはファンクションの動作は、SQL ストアドプロシージャまたはファンクションと同じです。ただし、プロシージャまたはファンクションのコードは C# または Visual Basic などの .NET 言語で記述され、その実行はデータベースサーバの外側 (つまり別の .NET 実行ファイル内) で行われます。
CREATE FUNCTION clr_interface( IN p1 INT, IN p2 UNSIGNED SMALLINT, IN p3 LONG VARCHAR) RETURNS INT EXTERNAL NAME 'CLRlib.dll::CLRproc.Run( int, ushort, string )' LANGUAGE CLR; |
EXTERNAL NAME perl-call LANGUAGE PERL 句 Perl 関数を外部環境で呼び出すには、関数インタフェースを EXTERNAL NAME 句で定義し、それに続いて LANGUAGE PERL 属性を指定します。
Perl ストアドプロシージャまたはファンクションの動作は、SQL ストアドプロシージャまたはファンクションと同じです。ただし、プロシージャまたはファンクションのコードは Perl で記述され、その実行はデータベースサーバの外側 (つまり Perl 実行インスタンス内) で行われます。
CREATE FUNCTION PerlWriteToConsole( IN str LONG VARCHAR) RETURNS INT EXTERNAL NAME '<file=PerlConsoleExample> WriteToServerConsole( $sa_perl_arg0 )' LANGUAGE PERL; |
EXTERNAL NAME php-call LANGUAGE PHP 句 PHP 関数を外部環境で呼び出すには、関数インタフェースを EXTERNAL NAME 句で定義し、それに続いて LANGUAGE PHP 属性を指定します。
PHP ストアドプロシージャまたはファンクションの動作は、SQL ストアドプロシージャまたはファンクションと同じです。ただし、プロシージャまたはファンクションのコードは PHP で記述され、その実行はデータベースサーバの外側 (つまり PHP 実行インスタンス内) で行われます。
CREATE FUNCTION PHPPopulateTable() RETURNS INT EXTERNAL NAME '<file=ServerSidePHPExample> ServerSidePHPSub()' LANGUAGE PHP; |
EXTERNAL NAME java-call LANGUAGE JAVA 句 Java メソッドを外部環境で呼び出すには、関数インタフェースを EXTERNAL NAME 句で定義し、それに続いて LANGUAGE JAVA 属性を指定します。
Java とのインタフェースとなるストアドプロシージャまたはファンクションの動作は、SQL ストアドプロシージャまたはファンクションと同じです。ただし、プロシージャまたはファンクションのコードは Java で記述され、その実行はデータベースサーバの外側 (つまり Java VM 内) で行われます。
CREATE FUNCTION HelloDemo( IN name LONG VARCHAR ) RETURNS INT EXTERNAL NAME 'Hello.main([Ljava/lang/String;)V' LANGUAGE JAVA; |
Java メソッドの引数と戻り値の記述子には次の意味があります。
フィールドタイプ | Java データ型 |
---|---|
B | byte |
C | char |
D | double |
F | float |
I | int |
J | long |
L class-name; | クラス class-name のインスタンス。クラス名は、完全に修飾された名前です。また、名前内のドットは / に置き換える必要があります。たとえば java/lang/String のようになります。 |
S | short |
V | void |
Z | Boolean |
[ | 配列の各次元ごとに 1 つ使用 |
CREATE FUNCTION 文はデータベースに関数を作成します。所有者を指定することによって他のユーザの関数を作成できます。関数は、SQL 式の一部として呼び出されます。
複数の関数からテンポラリテーブルを参照する場合、テンポラリテーブル定義が矛盾していたり、テーブルを参照する文がキャッシュされていたりすると、問題が発生する可能性があります。
自分が所有する外部関数を作成するには、CREATE PROCEDURE および CREATE EXTERNAL REFERENCE システム権限が必要です。
他のユーザが所有する外部関数を作成するには、CREATE ANY PROCEDURE または CREATE ANY OBJECT システム権限と、CREATE EXTERNAL REFERENCE システム権限が必要です。
テンポラリ関数の作成には権限は必要ありません。
オートコミット。
SQL/2008 外部言語環境の CREATE FUNCTION は SQL/2008 標準のコア機能ですが、SQL Anywhere でサポートされている一部のコンポーネントはオプションの SQL/2008 言語機能です。これらの機能のサブセットを次に示します。
SQL SECURITY 句は、オプションの言語機能 T324 です。
SQL 関数に LONG VARCHAR、LONG NVARCHAR、または LONG BINARY の値を渡す機能は、言語機能 T041 です。
LANGUAGE JAVA のサポートは、オプションの SQL/2008 言語機能 J621 です。
CREATE TABLE または DROP TRIGGER などの文を使用して外部関数内でスキーマオブジェクトを作成または変更する機能は、言語機能 T653 です。
CONNECT、EXECUTE IMMEDIATE、PREPARE、および DESCRIBE などの文を使用して外部関数内で動的 SQL 文を使用する機能は、言語機能 T654 です。
CREATE FUNCTION 文のいくつかの句は、ベンダー拡張です。これらを以下に示します。
LANGUAGES 句での C_ESQL32、C_ESQL64、C_ODBC32、C_ODBC64、CLR、PERL、PHP のサポートは、ベンダー拡張です。
external-call のフォーマットは実装依存です。
特定のルーチンパラメータのオプションの DEFAULT 句は、ベンダー拡張です。
オプションの OR REPLACE 句は、ベンダー拡張です。
Transact-SQL 外部ルーチンに対する CREATE FUNCTION は、Adaptive Server Enterprise でサポートされています。Adaptive Server Enterprise では、外部関数の外部環境 (SQL/2008 言語機能 J621) として LANGUAGE JAVA のみがサポートされています。
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2013, SAP AG or an SAP affiliate company. - SAP Sybase SQL Anywhere 16.0 |