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

SQL Anywhere 11.0.1 (日本語) » SQL Anywhere サーバ - プログラミング » SQL Anywhere データ・アクセス API » 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 関数またはストアド・プロシージャから結果セットを返す方法の詳細については、samples-dir\SQLAnywhere\ExternalEnvironments\CLR ディレクトリのサンプルを参照してください。

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

START EXTERNAL ENVIRONMENT CLR;

データベース・サーバが CLR を開始できない場合は、データベース・サーバが CLR 実行ファイルを検出できない可能性があります。CLR 実行ファイルは dbextclr11.exe です。このファイルが、使用しているデータベース・サーバのバージョンに応じて install-dir\Bin32 または install-dir\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;
    }
}

この関数をダイナミック・リンク・ライブラリにコンパイルすると、外部環境から呼び出すことができます。dbextclr11.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 サポートの使用に関する詳細および例については、samples-dir\SQLAnywhere\ExternalEnvironments\CLR ディレクトリのサンプルを参照してください。