ネイティブプロシージャーまたは外部プロシージャーへのインターフェイスを作成します。
CREATE [ OR REPLACE ] PROCEDURE [ owner.]procedure-name ( [ parameter[, ... ] ] ) [ RESULT ( result-column [, ... ] ) | NO RESULT SET ] [ DYNAMIC RESULT SETS integer-expression ] [ SQL SECURITY { INVOKER | DEFINER } ] { 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 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; |
CREATE PROCEDURE 文はデータベースにプロシージャーを作成します。DBA 権限があるユーザーは、所有者を指定することによって他のユーザーのプロシージャーを作成できます。プロシージャーは CALL 文で呼び出します。
ストアドプロシージャーが結果セットを返す場合、出力パラメーターを設定したり戻り値を返したりすることはできません。
複数のプロシージャーからテンポラリテーブルを参照する場合、テンポラリテーブル定義が矛盾していたり、テーブルを参照する文がキャッシュされていたりすると、問題が発生する可能性があります。
テンポラリプロシージャーを作成するのでないかぎり、RESOURCE 権限が必要です。
外部プロシージャーを作成する場合、および別のユーザーのプロシージャーを作成する場合、DBA 権限が必要です。
オートコミット。
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 © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |