Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 12.0.1 » SQL Anywhere サーバー プログラミング » SQL Anywhere 外部環境のサポート

 

CLR 外部環境

SQL Anywhere では、CLR ストアドプロシージャーおよび関数をサポートしています。CLR ストアドプロシージャーまたはファンクションの動作は、SQL ストアドプロシージャーまたはファンクションと同じです。ただし、プロシージャーまたはファンクションのコードは C# または Visual Basic などの .NET 言語で記述され、その実行はデータベースサーバーの外側 (つまり別の .NET 実行ファイル内) で行われます。この .NET 実行ファイルのインスタンスは、データベースごとに 1 つだけです。CLR 関数およびストアドプロシージャーを実行するすべての接続が、同じ .NET 実行インスタンスを使用します。ただし、ネームスペースは接続ごとに異なります。静的変数は接続の間持続しますが、接続間で共有することはできません。.NET バージョン 2.0 のみがサポートされています。

外部 CLR 関数またはプロシージャーを呼び出すには、ロードする DLL およびアセンブリ内で呼び出す関数を定義する EXTERNAL NAME 文字列を指定して、対応するストアドプロシージャーまたはファンクションを定義します。ストアドプロシージャーまたはファンクションを定義する際は、LANGUAGE CLR も指定する必要があります。次に、宣言の例を示します。

CREATE PROCEDURE clr_stored_proc( 
    IN p1 INT, 
    IN p2 UNSIGNED SMALLINT, 
    OUT p3 LONG VARCHAR) 
EXTERNAL NAME 'MyCLRTest.dll::MyCLRTest.Run( int, ushort, out string )' 
LANGUAGE CLR;

この例では、clr_stored_proc というストアドプロシージャーが、その実行時に DLL MyCLRTest.dll をロードし、関数 MyCLRTest.Run を呼び出します。clr_stored_proc プロシージャーは 3 つの SQL パラメーターを受け取ります。そのうち 2 つはそれぞれ INT 型と UNSIGNED SMALLINT 型の IN パラメーターで、もう 1 つは LONG VARCHAR 型の OUT パラメーターです。.NET 側で、この 3 つのパラメーターは int 型と ushort 型の入力引数、および string 型の出力引数に変換されます。out 引数のほかに、CLR 関数では ref 引数も使用できます。対応するストアドプロシージャーに INOUT パラメーターがある場合、ユーザーは ref CLR 引数を宣言する必要があります。

次の表は、CLR 引数の各種データ型と、それに対応する推奨される SQL データ型を示します。

CLR のデータ型 推奨される SQL データ型
bool bit
byte tinyint
short smallint
ushort unsigned smallint
int int
uint unsigned int
long bigint
ulong unsigned bigint
decimal numeric
float real
double double
DateTime timestamp
string long varchar
byte[] long binary

DLL の宣言では、相対パスまたは絶対パスのどちらかを指定できます。相対パスが指定された場合、外部 .NET 実行ファイルはそのパスだけでなく、それ以外の場所についても DLL を検索します。ただし、グローバルアセンブリキャッシュ (GAC) では DLL を検索しません。

既存の Java ストアドプロシージャーおよび関数と同様に、CLR ストアドプロシージャーおよび関数もサーバー側の要求をデータベースに戻して、結果セットを返すことができます。また、Java と同じように、Console.Out および Console.Error に出力される情報は、すべてデータベースサーバーメッセージウィンドウに自動的にリダイレクトされます。

サーバー側の要求の作成方法、および CLR 関数またはストアドプロシージャーから結果セットを返す方法の詳細については、%SQLANYSAMP12%\SQLAnywhere\ExternalEnvironments\CLR ディレクトリのサンプルを参照してください。

CLR をデータベースで使用するには、データベースサーバーが CLR 実行ファイルを検出して開始できることを確認してください。データベースサーバーが CLR 実行ファイルを検出して開始できるかどうかを確認するには、次の文を実行します。

START EXTERNAL ENVIRONMENT CLR;

データベースサーバーが CLR を開始できない場合は、データベースサーバーが CLR 実行ファイルを検出できない可能性があります。CLR 実行ファイルは dbextclr12.exe です。このファイルが、使用しているデータベースサーバーのバージョンに応じて %SQLANY12%\CE\Assembly\V2\CE\Assembly\V2\Bin32 または %SQLANY12%\CE\Assembly\V2\Bin64 にあることを確認してください。

START EXTERNAL ENVIRONMENT CLR 文は、データベースサーバーが CLR 実行ファイルを開始できるかどうかを確認する以外で使用することはありません。通常、CLR ストアドプロシージャーまたはファンクションを呼び出すと、CLR は自動的に開始されます。

これと同様に、CLR のインスタンスを停止するために STOP EXTERNAL ENVIRONMENT CLR 文を使用する必要もありません。インスタンスは、接続が切断されると自動的に停止します。ただし、CLR をこれ以上使用することがなく、一部のリソースを解放する必要がある場合は、STOP EXTERNAL ENVIRONMENT CLR 文を使用して接続のための CLR インスタンスを解放します。

Perl、PHP、Java 外部環境とは異なり、CLR 環境ではデータベースに何もインストールする必要がありません。したがって、CLR 外部環境を使用する前に INSTALL 文を実行する必要がありません。

次の例に示す C# で記述された関数は、外部環境で実行できます。

public class StaticTest
{
    private static int val = 0;

    public static int GetValue() {
        val += 1;
        return val;
    }
}

この関数をダイナミックリンクライブラリにコンパイルすると、外部環境から呼び出すことができます。dbextclr12.exe という実行イメージファイルがデータベースサーバーによって開始され、この実行イメージファイルがダイナミックリンクライブラリをロードします。この実行ファイルについては、さまざまなバージョンが SQL Anywhere に含まれています。たとえば Windows では、32 ビットと 64 ビットの実行ファイルがあります。1 つは 32 ビットバージョンのデータベースサーバー用、もう 1 つは 64 ビットバージョンのデータベースサーバー用です。

Microsoft C# コンパイラーを使用して、このアプリケーションをダイナミックリンクライブラリに構築するには、次のようなコマンドを使用します。上の例のソースコードは、StaticTest.cs というファイルにあるものと仮定しています。

csc /target:library /out:clrtest.dll StaticTest.cs

このコマンドは、コンパイル済みのコードを clrtest.dll という DLL に置きます。コンパイル済みの C# 関数 GetValue を呼び出すには、Interactive SQL を使用して、ラッパーを次のように定義します。

CREATE FUNCTION stc_get_value() 
RETURNS INT 
EXTERNAL NAME 'clrtest.dll::StaticTest.GetValue() int' 
LANGUAGE CLR;

CLR では、EXTERNAL NAME 文字列は 1 行の SQL 文で指定されます。場合によっては、EXTERNAL NAME 文字列に DLL のパスを含めて、DLL を検出できるようにする必要があります。依存アセンブリの場合 (たとえば、myLib.dllmyOtherLib.dll 内の関数を呼び出すコードがある、または何らかの形で前者が後者に依存する場合) は、.NET Framework によって依存性がロードされます。指定されたアセンブリは CLR 外部環境によってロードされますが、依存アセンブリが確実にロードされるようにするためには追加の手順が必要になる場合があります。解決策としては、.NET Framework にインストールされている Microsoft gacutil ユーティリティを使用してすべての依存性をグローバルアセンブリキャッシュ (GAC) に登録するという方法があります。カスタム開発のライブラリを使用する場合、gacutil を使用して GAC に登録する前に、厳密な名前キーでライブラリが署名してある必要があります。

サンプルのコンパイル済み C# 関数を実行するには、次の文を実行します。

SELECT stc_get_value();

C# 関数が呼び出されるたびに、整数値の結果が新しく生成されます。返される値は、1、2、3、の順に続きます。

データベースでの CLR サポートの使用に関する詳細および例については、%SQLANYSAMP12%\SQLAnywhere\ExternalEnvironments\CLR ディレクトリのサンプルを参照してください。