共用方式為


逐步解說:偵錯 SQL CLR 使用者定義的彙總

更新:2007 年 11 月

這個主題適用於:

版本

Visual Basic

C#

C++

Web Developer

Express 版

標題不適用於 標題不適用於 標題不適用於 標題不適用於

Standard 版

標題不適用於 標題不適用於 標題不適用於 標題不適用於

Pro/Team 版

標題適用於 標題適用於 標題適用於 標題適用於

表格圖例:

標題適用於

套用

標題不適用於

不套用

預設會套用主題但隱藏命令

預設隱藏的命令。

這個範例將示範如何偵錯 CLR SQL 使用者定義的彙總。這個範例會在 AdventureWorks 範例資料庫中建立稱為 Concatenate 的新 CLR SQL 彙總函式。當您在 SQL 陳述式中叫用這個函式時,其會將欄位中所有的值結合在一起指定做為輸入參數。

注意事項:

您所看見的對話方塊與功能表命令可能會與 [說明] 中所描述的有所不同,視您所使用的設定或版本而定。若要變更設定,請從 [工具] 功能表中選擇 [匯入和匯出設定]。如需詳細資訊,請參閱 Visual Studio 設定

若要偵錯 CLR SQL 彙總函式

  1. 在新的 SQL Server 專案中,建立與 AdventureWorks 範例資料庫的連線。如需詳細資訊,請參閱 HOW TO:連接資料庫

  2. 使用下列第一個範例區段的程式碼建立新的函式,並將其命名為 Concatenate.cs。如需詳細資訊,請參閱 HOW TO:使用 SQL Server 專案類型開發

  3. 藉由將指令碼包含在 SELECT 陳述式中,加入能夠測試函式的指令碼。在 [方案總管] 中,以滑鼠右鍵按一下 [TestScripts] 目錄,再選取 [加入測試指令碼],然後插入此逐步解說第二個範例區段中的程式碼。使用名稱 Concatenate.sql 來儲存檔案。以滑鼠右鍵按一下檔名,然後按一下 [設定為預設偵錯指令碼]。

  4. 在 if 陳述式 Accumulate 方法中的 Concatenate.cs放置一個中斷點。若要這麼做,請在 [文字編輯器] 視窗的灰色左邊緣按一下,並按一下 [偵錯] 功能表上的 [啟動] 來編譯和部署專案,並進行單元測試。當中斷點上出現以黃色箭頭表示的指令指標時,即表示您正在偵錯函式。

  5. 嘗試不同的偵錯功能。

    1. Concatenate.sql 內的指令碼中,每個構成 GROUP BY 子句的資料列都會執行 Accumulate 方法一次。重複按 [偵錯] 功能表中的 [偵錯],您便可以監看方法結果的建置方式。

    2. 在 [區域變數] 視窗中,開啟包含目前正在處理中之存放區名稱的變數 value。

    3. 按一下變數 this。這個函式會傳回子節點 intermediateResult,而其包含目前存放區在內的所有存放區名稱,並且會以逗號分隔的方式串連在一起。

    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

請參閱

工作

HOW TO:建立及執行 CLR SQL Server 彙總

其他資源

SQL CLR 資料庫偵錯