チュートリアル : SQL CLR のユーザー定義のテーブル値関数のデバッグ

このトピックの内容は、次の製品に該当します。

エディション

Visual Basic

C#

C++

Web Developer

Express

トピック該当なし トピック該当なし トピック該当なし トピック該当なし

[標準]

トピック該当なし トピック該当なし トピック該当なし トピック該当なし

Pro/Team

トピック該当 トピック該当 トピック該当 トピック該当

この例では、SQL Server 共通言語ランタイム (SQL CLR) のユーザー定義のテーブル値関数 (UDF: User Defined Table-Valued Function) をデバッグする方法について説明します。

SQL CLR オブジェクトをデバッグしようとしたときに "ユーザーによってキャンセルされました" というメッセージが表示された場合は、Visual Studio を実行しているコンピューターと SQL Server を実行しているコンピューターの両方を手動で構成する必要があります。 詳細については、「方法: Transact-SQL デバッグと SQL CLR デバッグを実行するためのコンピューターを構成する」を参照してください。

注意

実際に画面に表示されるダイアログ ボックスとメニュー コマンドは、アクティブな設定またはエディションによっては、ヘルプの説明と異なる場合があります。 設定を変更するには、[ツール] メニューの [設定のインポートとエクスポート] をクリックします。 詳細については、「設定の操作」を参照してください。

SQL CLR のユーザー定義のテーブル値関数をデバッグするには

  1. 新しい SQL CLR プロジェクトで、データベースへの接続を確立します。 詳細については、「方法 : データベースへの接続します。」を参照してください。

  2. 下のセクションにある最初のサンプル コードを使用して、新しい関数を作成し、TableOfPrimes.cs という名前を付けます。 詳細については、「方法 : SQL Server プロジェクトの種類と開発します。」を参照してください。

  3. SELECT ステートメントに含めて、関数をテストするスクリプトを追加します。 ソリューション エクスプローラーTestScripts ディレクトリを右クリックし、[テスト スクリプトの追加] をクリックして、後述する 2 つ目のサンプルにあるコードを挿入します。 ファイルに TestPrime.sql という名前を付けて、保存します。 ファイル名を右クリックし、[既定のデバッグ スクリプトの設定] をクリックします。

  4. TableOfPrimes.cs にブレークポイントを設定し、[デバッグ] メニューの [開始] をクリックして、プロジェクトのコンパイル、配置、単体テストを実行します。 黄色の矢印で表される命令ポインターがブレークポイントに表示されて、SQL CLR コードのデバッグが行われます。

  5. いろいろなデバッグ機能を試してください。

    1. [デバッグ] メニューの [ステップ イン] を繰り返しクリックすると、関数の行ごとの実行を確認できます。

    2. 1 ステップずつ実行すると、[ローカル] ウィンドウと [ウォッチ] ウィンドウを使用して、異なるメンバーの値を確認できます。

    3. 関数のデバッグを終了するには、もう一度 [続行] をクリックします。

    4. [出力] ウィンドウで、[出力元の表示] ドロップダウン リストの [データベース出力] をクリックすると、TestPrimes.sql スクリプトの 2 つのクエリの実行結果を確認できます。

使用例

これは、イベント ログを読み取るコードです。

using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;

public partial class UserDefinedFunctions
{
    struct primeIndex
    {
        public int n;
        public int p;
        public primeIndex(int n, int p)  
        { 
            this.n = n; this.p = p;
        }
    }

    static bool isPrime(int p)
    {
        if (p < 2) return false;
        if (p == 2) return true;
        if (p % 2 == 0) return false;
        for (int d = 3; d * d <= p; d+=2)
        {
            if (p % d == 0) return false;
        }
        return true;
    }

    static int nextPrime(int p)
    {
        int result = p + 1;
        while (!isPrime(result)) result++;
        return result;
    }

    [SqlFunction(FillRowMethodName = "Fill", TableDefinition = "n int,p int,est float")]
    public static IEnumerable TableOfPrimes(int n)
    {
        int p = 1;
        for (int i = 1; i <= n; i++)
        {
            p = nextPrime(p);
            yield return new primeIndex(i, p);
        }
    }

    private static void Fill(object source, out int n, out int p, out SqlDouble est)
    {
        primeIndex pi = (primeIndex)source;
        n = pi.n;
        p = pi.p;
        if (n <5)
            est = SqlDouble.Null;
        else
        {
            double log = Math.Log(n);
            double loglog = Math.Log(log);
            est = n * (log + loglog - 1 + loglog / log - 2 / log); 
        }
    }
}

これは、関数を呼び出すテスト スクリプトです。

SELECT n,p,est FROM dbo.TableOfPrimes(50)

SELECT TOP 10 n, p, est, est/p AS factor FROM dbo.TableOfPrimes(500) ORDER BY factor DESC

SELECT TOP 10 n, p, est, est/p AS factor FROM dbo.TableOfPrimes(1000) WHERE n>500 ORDER BY factor DESC

参照

処理手順

方法: 共通言語ランタイム統合機能を使用して SQL Server のユーザー定義関数を作成および実行する