ネイティブプロシージャまたは外部プロシージャへのインタフェースを作成します。
CREATE [ OR REPLACE ] PROCEDURE [ owner.]procedure-name ( [ parameter[, ... ] ] ) [ SQL SECURITY { INVOKER | DEFINER } ] [ RESULT ( result-column [, ... ] ) | NO RESULT SET ] [ DYNAMIC RESULT SETS integer-expression ] { 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 : [ parameter-mode ] parameter-name data-type [ DEFAULT expression ] | SQLCODE | SQLSTATE
parameter-mode : IN | OUT | INOUT
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; }
外部プロシージャまたはネイティブプロシージャを呼び出す永続的なストアドプロシージャの作成には、さまざまなプログラミング言語を使用できます。PROC は PROCEDURE の同義語として使用できます。
OR REPLACE 句 OR REPLACE を指定すると、新しいプロシージャが作成されるか、同じ名前の既存のプロシージャが置き換えられます。この句によって、プロシージャの定義は変更されますが、既存の権限は保持されます。使用中のプロシージャを置き換えようとすると、エラーが返されます。
パラメータ パラメータ名は、カラム名など他のデータベース識別子に対するルールに従って付けてください。これらは有効な SQL データ型にする必要があります。
パラメータには、IN、OUT、INOUT のいずれかのキーワードをプレフィクスとして付けることができます。これらの値のいずれも指定しない場合、パラメータはデフォルトで INOUT になります。キーワードには次の意味があります。
IN このパラメータは、プロシージャに値を与える式です。
OUT このパラメータは、プロシージャから値を受け取ることがある変数です。
INOUT このパラメータはプロシージャに値を与え、プロシージャから新しい値を受け取ることがある変数です。
CALL 文を使ってプロシージャを実行する場合、必ずしもすべてのパラメータを指定する必要はありません。CREATE PROCEDURE 文の中にデフォルト値がある場合、不明のパラメータにデフォルト値を割り当てます。CALL に引数が指定されておらず、デフォルトも設定されていない場合には、エラーが発生します。
SQLSTATE と SQLCODE は、プロシージャが終了するときに、SQLSTATE または SQLCODE 値を出力する、特別な OUT パラメータです。SQLSTATE と SQLCODE の特別値は、プロシージャのリターンステータスのテストを目的として、プロシージャ呼び出しの直後にチェックできます。
SQLSTATE と SQLCODE 特別値は、その次の SQL 文によって修正されます。SQLSTATE と SQLCODE をプロシージャ引数として与えると、リターンコードは変数の中に格納されます。
OR REPLACE (CREATE OR REPLACE PROCEDURE) を指定すると、新しいプロシージャが作成されるか、同じ名前の既存のプロシージャが置き換えられます。この句によって、プロシージャの定義は変更されますが、既存の権限は保持されます。使用中のプロシージャを置き換えようとすると、エラーが返されます。
TEMPORARY 外部呼び出しプロシージャは作成できません。
RESULT 句 RESULT 句は結果セットのカラムの数と型を宣言します。RESULT キーワードに続くカッコで囲まれたリストは、結果カラムの名前と型を定義します。CALL 文が記述されていると、この情報を Embedded SQL DESCRIBE または ODBC SQLDescribeCol が返します。
Embedded SQL (LANGUAGE C_ESQL32、LANGUAGE C_ESQL64) 外部プロシージャまたは ODBC (LANGUAGE C_ODBC32、LANGUAGE C_ODBC64) 外部プロシージャは、結果セットを返さないか、1 つの結果セットを返すことができます。
Perl または PHP (LANGUAGE PERL、LANGUAGE PHP) 外部プロシージャは、結果セットを返すことができません。データベースサーバによってロードされるネイティブ関数を呼び出すプロシージャも、結果セットを返すことができません。
CLR または Java (LANGUAGE CLR、LANGUAGE JAVA) 外部プロシージャは、結果セットを返さないか、1 つ以上の結果セットを返すことができます。
プロシージャは、その実行方法に応じて、それぞれカラム数が異なる複数の結果セットを生成する場合があります。たとえば次のプロシージャは、2 カラムを返す場合も、1 カラムを返す場合もあります。
CREATE PROCEDURE names( IN formal char(1)) BEGIN IF formal = 'n' THEN SELECT GivenName FROM GROUPO.Employees ELSE SELECT Surname, GivenName FROM Employees END IF END; |
これらの結果セットプロシージャは RESULT 句を指定しないで記述するか、Transact-SQL で記述します。これらの使用には、次の制約があります。
Embedded SQL 正しい形式の結果セットを取得するには、結果セットのカーソルが開かれてからローが返されるまでの間に、プロシージャコールを記述 (DESCRIBE) します。DESCRIBE 文の CURSOR cursor-name 句は必須です。
ODBC、OLE DB、ADO.NET 変数結果セットプロシージャは、これらのインタフェースを使用するアプリケーションで使用できます。結果セットの記述は、ドライバまたはプロバイダによって実行されます。
Open Client アプリケーション 変数結果セットプロシージャは Open Client アプリケーションで使用できます。
プロシージャが結果セットを 1 つしか返さない場合、RESULT 句を使用してください。この句を使用すると、カーソルがオープンした後で ODBC と Open Client のアプリケーションが結果セットを記述し直すのを防ぐことができます。
複数の結果セットを処理するために ODBC は、プロシージャが定義した結果セットではなく、現在実行中のカーソルを記述します。したがって、ODBC はいつもプロシージャ定義の RESULT 句内で定義されているカラム名を記述するわけではありません。この問題を回避するには、結果セットを生成する SELECT 文でカラムエイリアスを使用します。
NO RESULT SET 句 このプロシージャによって結果セットが返されないことを宣言します。この宣言によって、パフォーマンスが向上することがあります。
DYNAMIC RESULT SETS 句 この句は、LANGUAGE CLR 呼び出しまたは LANGUAGE JAVA 呼び出しで使用します。DYNAMIC RESULT SETS 句を使用して、プロシージャによって返される動的結果セットの数を指定します。RESULT 句が指定され、DYNAMIC RESULT SETS 句が指定されていない場合、動的結果セットの数は 1 とみなされます。RESULT 句も DYNAMIC RESULT SETS 句も指定されていない場合、結果セットは予測されず、結果セットが生成されるとエラーになります。
C_ESQL32、C_ESQL64、C_ODBC32、C_ODBC64 外部環境も結果セット (CLR や JAVA など) を返しますが、これらは 1 つの動的結果セットに制限されます。
Perl または PHP (LANGUAGE PERL、LANGUAGE PHP) 外部関数を呼び出すプロシージャは、結果セットを返すことができません。データベースサーバによってロードされるネイティブ関数を呼び出すプロシージャも、結果セットを返すことができません。
SQL SECURITY 句 SQL SECURITY 句は、INVOKER (プロシージャを呼び出すユーザ) または DEFINER (プロシージャを所有するユーザ) としてプロシージャが実行されるかどうかを定義します。デフォルトは DEFINER です。外部呼び出しの場合、この句は、外部環境での修飾されていないオブジェクト参照に対して所有者のコンテキストを確立します。
SQL SECURITY INVOKER が指定されている場合は、プロシージャを呼び出すユーザごとに注釈を行う必要があるためメモリ使用量が増えます。また、SQL SECURITY INVOKER が指定されている場合は、呼び出し側としても名前の決定が行われます。このため、すべてのオブジェクト名 (テーブル、プロシージャなど) を該当する所有者で修飾する場合は注意が必要です。たとえば、user1 が次のプロシージャを作成するとします。
CREATE PROCEDURE user1.myProcedure() RESULT( columnA INT ) SQL SECURITY INVOKER BEGIN SELECT columnA FROM table1; END; |
user2 がこのプロシージャを実行しようとし、テーブル user2.table1 が存在しない場合、テーブルルックアップエラーが生じます。さらに、user2.table1 が存在する場合は、意図する user1.table1 の代わりにこのテーブルが使用されます。このような状況を防ぐには、文においてテーブル参照を修飾します (単なる table1 ではなく、user1.table1 とします)。
EXTERNAL NAME 句 LANGUAGE 属性なしで EXTERNAL NAME 句を使用するプロシージャは、C などのプログラミング言語で記述されたネイティブ関数へのインタフェースを定義します。ネイティブ関数は、データベースサーバによってそのアドレス領域にロードされます。
library 名にはファイル拡張子を付けることができます。これは通常、Windows では .dll、UNIX では .so です。拡張子がない場合、ライブラリに対するプラットフォーム固有のデフォルトのファイル拡張子が追加されます。次に、正式な例を示します。
CREATE PROCEDURE mystring( IN instr LONG VARCHAR ) EXTERNAL NAME 'mystring@mylib.dll;Unix:mystring@mylib.so'; |
上記の EXTERNAL NAME 句を、プラットフォーム固有のデフォルト値を使用して簡単に記述すると、次のようになります。
CREATE PROCEDURE mystring( IN instr LONG VARCHAR ) EXTERNAL NAME 'mystring@mylib'; |
呼び出されると、関数を含むライブラリがデータベースサーバのアドレス領域にロードされます。ネイティブ関数は、サーバの一部として実行されます。この場合、関数が原因で障害が発生すると、データベースサーバは終了されます。したがって、外部環境での関数のロードと実行には、LANGUAGE 属性を使用することをおすすめします。関数が原因で外部環境に障害が発生しても、データベースサーバは実行し続けます。
operating-system がサポートされている構文で operating-system を指定しないと、プロシージャがすべてのプラットフォームで稼働すると見なされます。いずれかの呼び出しで Unix を指定すると、他の呼び出しは Windows 用であると見なされます。
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 PROCEDURE ODBCinsert( IN ProductName CHAR(30), IN ProductDescription CHAR(50) ) NO RESULT SET 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 PROCEDURE clr_interface( IN p1 INT, IN p2 UNSIGNED SMALLINT, OUT p3 LONG VARCHAR) NO RESULT SET EXTERNAL NAME 'CLRlib.dll::CLRproc.Run( int, ushort, out string )' LANGUAGE CLR; |
EXTERNAL NAME perl-call LANGUAGE PERL 句 Perl 関数を外部環境で呼び出すには、プロシージャインタフェースを EXTERNAL NAME 句で定義し、それに続いて LANGUAGE PERL 属性を指定します。
Perl ストアドプロシージャまたはファンクションの動作は、SQL ストアドプロシージャまたはファンクションと同じです。ただし、プロシージャまたはファンクションのコードは Perl で記述され、その実行はデータベースサーバの外側 (つまり Perl 実行インスタンス内) で行われます。
次に、プロシージャ定義の例を示します。
CREATE PROCEDURE PerlWriteToConsole( IN str LONG VARCHAR) NO RESULT SET 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 PROCEDURE PHPPopulateTable() NO RESULT SET EXTERNAL NAME '<file=ServerSidePHPExample> ServerSidePHPSub()' LANGUAGE PHP; |
EXTERNAL NAME java-call LANGUAGE JAVA 句 Java メソッドを外部環境で呼び出すには、プロシージャインタフェースを EXTERNAL NAME 句で定義し、それに続いて LANGUAGE JAVA 属性を指定します。
Java とのインタフェースとなるストアドプロシージャまたはファンクションの動作は、SQL ストアドプロシージャまたはファンクションと同じです。ただし、プロシージャまたはファンクションのコードは Java で記述され、その実行はデータベースサーバの外側 (つまり Java VM 内) で行われます。
次に、プロシージャ定義の例を示します。
CREATE PROCEDURE HelloDemo( IN name LONG VARCHAR ) NO RESULT SET 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 PROCEDURE 文はデータベースにプロシージャを作成します。所有者を指定することによって他のユーザのプロシージャを作成できます。プロシージャは CALL 文で呼び出します。
ストアドプロシージャが結果セットを返す場合、出力パラメータを設定したり戻り値を返したりすることはできません。
複数のプロシージャからテンポラリテーブルを参照する場合、テンポラリテーブル定義が矛盾していたり、テーブルを参照する文がキャッシュされていたりすると、問題が発生する可能性があります。
ユーザ本人が所有する外部プロシージャを作成するには、CREATE PROCEDURE システム権限が必要です。
他のユーザが所有する外部プロシージャを作成するには、CREATE ANY PROCEDURE または CREATE ANY OBJECT システム権限が必要です。
オートコミット。
SQL/2008 外部言語環境の CREATE PROCEDURE は SQL/2008 標準のコア機能ですが、SQL Anywhere でサポートされている一部のコンポーネントはオプションの SQL/2008 言語機能です。これらの機能のサブセットを次に示します。
SQL SECURITY 句は、オプションの SQL/2008 言語機能 T324 です。
外部プロシージャに LONG VARCHAR、LONG NVARCHAR、または LONG BINARY 値を渡す機能は、SQL/2008 言語機能 T041 です。
CREATE TABLE または DROP TRIGGER などの文を使用して外部プロシージャ内でスキーマオブジェクトを作成または変更する機能は、SQL/2008 言語機能 T653 です。
CONNECT、EXECUTE IMMEDIATE、PREPARE、および DESCRIBE などの文を使用して外部プロシージャ内で動的 SQL 文を使用する機能は、SQL/2008 言語機能 T654 です。
JAVA 外部プロシージャには、SQL/2008 言語機能 J621 が埋め込まれています。
CREATE PROCEDURE 文のいくつかの句は、ベンダー拡張です。これらを以下に示します。
LANGUAGES 句での C_ESQL32、C_ESQL64、C_ODBC32、C_ODBC64、CLR、PERL、および PHP のサポートは、ベンダー拡張です。SQL/2008 標準では、オプションの言語機能 B122 として "C" が environment-name としてサポートされています。
external-call のフォーマットは実装依存です。
RESULT 句と NO RESULT SET 句は、ベンダー拡張です。SQL/2008 標準では、RETURNS 句が使用されます。
特定のルーチンパラメータのオプションの DEFAULT 句は、ベンダー拡張です。
オプションの OR REPLACE 句は、ベンダー拡張です。
Transact-SQL 外部ルーチンに対する CREATE PROCEDURE は、Adaptive Server Enterprise でサポートされています。Adaptive Server Enterprise では、C 言語および Java 言語の外部ルーチンがサポートされています。
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2013, SAP AG or an SAP affiliate company. - SAP Sybase SQL Anywhere 16.0 |