CLR 統合の概要
このトピックでは、Microsoft SQL Server と .NET Framework CLR (共通言語ランタイム) との統合を使用して、データベース オブジェクトをコンパイルするために必要な名前空間とライブラリの概要について説明します。 また、Microsoft Visual C# を使用した簡単な CLR ストアド プロシージャを記述、コンパイル、および実行する方法についても説明します。
必要な名前空間
SQL Server 2005 以降では、基本的な CLR データベース オブジェクトの開発に必要なコンポーネントは、SQL Server と共にインストールされます。 CLR 統合機能は、.NET Framework の一部である system.data.dll というアセンブリで公開されます。 このアセンブリは、.NET Framework ディレクトリ内だけでなく、GAC (グローバル アセンブリ キャッシュ) 内にもあります。 通常、このアセンブリへの参照は、コマンド ライン ツールと Microsoft Visual Studio の両方で自動的に追加されるので、手動で追加する必要はありません。
system.data.dll アセンブリには、CLR データベース オブジェクトのコンパイルに必要な次の名前空間が含まれています。
System.Data
System.Data.Sql
Microsoft.SqlServer.Server
System.Data.SqlTypes
簡単な "Hello World" ストアド プロシージャの作成
次の Visual C# コードまたは Microsoft Visual Basic コードをコピーしてテキスト エディターに貼り付け、"helloworld.cs" または "helloworld.vb" というファイル名を付けて保存してください。
using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
public class HelloWorldProc
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void HelloWorld(out string text)
{
SqlContext.Pipe.Send("Hello world!" + Environment.NewLine);
text = "Hello world!";
}
}
Imports System
Imports System.Data
Imports Microsoft.SqlServer.Server
Imports System.Data.SqlTypes
Imports System.Runtime.InteropServices
Public Class HelloWorldProc
<Microsoft.SqlServer.Server.SqlProcedure> _
Public Shared Sub HelloWorld(<Out()> ByRef text as String)
SqlContext.Pipe.Send("Hello world!" & Environment.NewLine)
text = "Hello world!"
End Sub
End Class
この簡単なプログラムには、パブリック クラスの静的メソッドが 1 つ含まれています。 このメソッドでは、SqlContext と SqlPipe という 2 つの新しいクラスを使用して、簡単なテキスト メッセージを出力するマネージ データベース オブジェクトを作成します。 また、このメソッドでは、文字列 "Hello world!" を out パラメーターの値として割り当てます。 このメソッドを SQL Server のストアド プロシージャとして宣言すれば、Transact-SQL ストアド プロシージャと同じ方法で実行できます。
ここでは、このプログラムをライブラリとしてコンパイルし、SQL Server に読み込んで、ストアド プロシージャとして実行します。
"Hello World" ストアド プロシージャのコンパイル
SQL Server では、Microsoft .NET Framework の再配布ファイルが既定でインストールされます。 インストールされるファイルには、Visual C# プログラムと Visual Basic プログラム用のコマンド ライン コンパイラである csc.exe と vbc.exe が含まれています。 サンプルをコンパイルする前に、csc.exe または vbc.exe が格納されたディレクトリを指すようにパス変数を変更する必要があります。 .NET Framework の既定のインストール パスは、次のとおりです。
C:\Windows\Microsoft.NET\Framework\(version)
version は、インストールされた再配布可能な .NET Framework のバージョン番号を表します。 次に例を示します。
C:\Windows\Microsoft.NET\Framework\v2.0.31113
.NET Framework ディレクトリをパスに追加した後、次のコマンドを実行してサンプル ストアド プロシージャをアセンブリにコンパイルできます。 アセンブリへのコンパイルを可能にするのは /target オプションです。
Visual C# ソース ファイルの場合は、次のコマンドを実行します。
csc /target:library helloworld.cs
Visual Basic ソース ファイルの場合は、次のコマンドを実行します。
vbc /target:library helloworld.vb
これらのコマンドでは、/target オプションを使用してライブラリ DLL をビルドすることを指定し、Visual C# コンパイラまたは Visual Basic コンパイラを起動します。
"Hello World" ストアド プロシージャの SQL Server への読み込みと実行
サンプル プロシージャを正常にコンパイルしたら、SQL Server でそのプロシージャをテストできます。 プロシージャをテストするには、SQL Server Management Studio を起動し、適切なテスト データベース (AdventureWorks サンプル データベースなど) に接続して新しいクエリを作成します。
SQL Server では、CLR (共通言語ランタイム) コードを実行する機能は、既定ではオフに設定されています。 CLR コードを有効にするには、sp_configure システム ストアド プロシージャを使用します。 詳細については、「CLR 統合の有効化」を参照してください。
ストアド プロシージャにアクセスするには、アセンブリを作成する必要があります。 この例では、C:\ ディレクトリに helloworld.dll アセンブリが作成されているものとします。 クエリに次の Transact-SQL ステートメントを追加します。
CREATE ASSEMBLY helloworld from 'c:\helloworld.dll' WITH PERMISSION_SET = SAFE
アセンブリを作成した後、次のように CREATE PROCEDURE ステートメントを使用すると、HelloWorld メソッドにアクセスできるようになります。 ここではストアド プロシージャ "hello" を呼び出します。
CREATE PROCEDURE hello
@i nchar(25) OUTPUT
AS
EXTERNAL NAME helloworld.HelloWorldProc.HelloWorld
-- if the HelloWorldProc class is inside a namespace (called MyNS),
-- the last line in the create procedure statement would be
-- EXTERNAL NAME helloworld.[MyNS.HelloWorldProc].HelloWorld
作成したプロシージャは、Transact-SQL で記述された通常のストアド プロシージャと同様に実行できます。 たとえば、次のコマンドを実行します。
DECLARE @J nchar(25)
EXEC hello @J out
PRINT @J
これにより、SQL Server Management Studio のメッセージ ウィンドウに次の出力結果が表示されます。
Hello world!
Hello world!
"Hello World" サンプル ストアド プロシージャの削除
サンプル ストアド プロシージャの実行を完了したら、テスト データベースからこのプロシージャとアセンブリを削除できます。
最初に、次のように drop procedure コマンドを使用してプロシージャを削除します。
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'hello')
drop procedure hello
プロシージャを削除したら、サンプル コードが含まれたアセンブリを次のように削除できます。
IF EXISTS (SELECT name FROM sys.assemblies WHERE name = 'helloworld')
drop assembly helloworld