次の方法で共有


チュートリアル : SQL CLR のユーザー定義集計のデバッグ

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

エディション

Visual Basic

C#

C++

Web Developer

Express

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

[標準]

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

Pro/Team

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

この例では、SQL Server 共通言語ランタイム (SQL CLR) のユーザー定義集計をデバッグする方法について説明します。 この例により、AdventureWorks サンプル データベースに Concatenate という、新しい SQL CLR 集計関数が作成されます。 SQL ステートメントでこの関数を呼び出すと、入力パラメーターで指定した列の値がすべて連結されます。

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

注意

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

CLR SQL 集計関数をデバッグするには

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

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

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

  4. if ステートメントの Accumulate メソッド内にある Concatenate.cs にブレークポイントを設定します。 そのためには、テキスト エディター ウィンドウの網かけの左端余白をクリックします。次に [デバッグ] メニューの [デバッグ開始] をクリックして、プロジェクトのコンパイル、配置、単体テストを実行します。 黄色の矢印で表される命令ポインターがブレークポイントに表示されて、関数のデバッグが行われます。

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

    1. Concatenate.sql のスクリプト内の GROUP BY 句を構成する各行について、Accumulate メソッドが 1 回実行されます。 [デバッグ] メニューの [ステップ イン] を繰り返しクリックすることにより、このメソッドの結果が生成される過程を観察できます。

    2. [ローカル] ウィンドウで、変数 value を開きます。この変数には、現在処理中のストア名が含まれます。

    3. 変数 this をクリックします。 この関数から子ノード intermediateResult が返されます。この子ノードには、現在のものまでのすべてのストア名がコンマ区切りで 1 つに連結されています。

    4. テキスト エディターで、intermediateResult 変数をダブルクリックして選択します。 intermediateResult を [ウォッチ] ウィンドウにドラッグし、ウィンドウの任意の場所にドロップします。 ウォッチする変数のリストに追加されます。

    5. メソッドを、数回ステップ実行します。 intermediateResult の値は、メソッドを実行するたびに変わり、新規のストア名が末尾に連結されます。

    6. ブレークポイントをクリックして削除し、Terminate メソッド内の最初のステートメントにブレークポイントを追加します。 このメソッドから呼び出し元に結果が返されます。 ステップ インするには、[デバッグ] メニューの [デバッグ開始] をクリックします。 [デバッグ] メニューの [ステップ イン] をクリックすると、ステップ実行できます。 return ステートメントにヒットしたときは停止します。

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

使用例

これは、この例で使用される集計関数のコードです。

using System;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.IO;
using System.Text;
[Serializable]
[SqlUserDefinedAggregate( 
    //use CLR serialization to serialize the intermediate result. 
    Format.UserDefined, 
    //Optimizer property: 
    IsInvariantToNulls=true,
    //Optimizer property: 
    IsInvariantToDuplicates=false,
    //Optimizer property: 
    IsInvariantToOrder=false,
    //Maximum size in bytes of persisted value: 
    MaxByteSize=8000)
] 
public class Concatenate: IBinarySerialize 
{ 
    /// <summary> 
    /// Variable holds intermediate result of the concatenation 
    /// </summary> 
    private StringBuilder intermediateResult; 
    /// <summary> 
    /// Initialize the internal data structures 
    /// </summary> 
    public void Init( ) 
    { 
        intermediateResult = new StringBuilder(); 
    } 
    /// <summary> 
    /// Accumulate the next value, nop if the value is null 
    /// </summary> 
    /// <param name="value"></param> 
    public void Accumulate(SqlString value) 
    { 
        if(value.IsNull) 
        { 
            return; 
        } 
        intermediateResult.Append(value.Value).Append(','); 
    } 
    /// <summary> 
    /// Merge the partially computed aggregate with this aggregate. 
    /// </summary> 
    /// <param name="other"></param> 
    public void Merge( Concatenate other) 
    { 
        intermediateResult.Append(other.intermediateResult); 
    } 
    /// <summary> 
    /// Called at end of aggregation, to return results. 
    /// </summary> 
    /// <returns></returns> 
    public SqlString Terminate() 
    { 
        string output = string.Empty; 
        //Delete the trailing comma, if any .
        if (intermediateResult != null && intermediateResult.Length > 0) 
            output = intermediateResult.ToString(0, intermediateResult.Length-1); 
        return new SqlString(output); 
    } 
    public void Read(BinaryReader r) 
    { 
        intermediateResult = new StringBuilder(r.ReadString()); 
    } 
    public void Write(BinaryWriter w) 
    { 
        w.Write(intermediateResult.ToString()); 
    } 
}

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

SELECT scu.SalesPersonID, dbo.Concatenate(sst.Name)
FROM Sales.Customer as scu 
INNER JOIN Sales.Store as sst
    ON scu.CustomerID    = sst.CustomerID
INNER JOIN Sales.SalesPerson as spr
    ON scu.SalesPersonID = spr.SalesPersonID
WHERE    scu.SalesPersonID = 283
GROUP BY scu.SalesPersonID

参照

処理手順

方法: 共通言語ランタイム統合機能を使用して SQL Server の集計を作成および実行する