共用方式為


HOW TO:偵錯多層資料庫應用程式

更新:2007 年 11 月

這個主題適用於:

版本

Visual Basic

C#

C++

Web Developer

Express 版

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

Standard 版

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

Pro/Team 版

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

表格圖例:

標題適用於

套用

標題不適用於

不套用

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

預設隱藏的命令。

本主題將包含示範偵錯多層應用程式的範例程式碼,以及描述從用戶端或多層應用程式中的應用程式碼,偵錯至 SQL Server 2005 內所執行的資料庫物件程式碼的必要步驟。

應用程式層和資料庫層之間的轉換需要在目標層設定中斷點;否則當您嘗試逐步執行至目標層時,程式碼將會繼續執行而不停止。但是在資料庫層中,T-SQL 和 SQL CLR 程式碼之間的轉換不需要中斷點來啟用在兩者間的逐步執行。

下列範例會使用 AdventureWorks 資料庫,並且在不同的層以及語言之間往前或往後逐步執行。範例的用意是用來說明這些轉換,而這顯然並不是真實的企業案例。

呼叫了三個預存程序:

  • DeleteCurrency 是使用指定貨幣代碼刪除貨幣的 SQL CLR 預存程序。

  • DeleteCurrency_T_SQL 執行相同的動作,但是是以 T-SQL 撰寫。

  • DeleteCurrencyDriver 會使用指定欲刪除貨幣代碼的輸入參數,來呼叫前面的兩個預存程序。

應用程式碼會呼叫三個預存程序,以傳遞貨幣代碼參數。這兩個「非驅動程式」預存程序會從兩個不同的內容呼叫:從 DeleteCurrencyDriver 以及直接從應用程式。在第一個內容中,您可以從 DeleteCurrencyDriver 逐步執行至另外兩個預存程序。從應用程式呼叫時,您就無法直接逐步執行至這兩個預存程序,必須在預存程序中設定中斷點。

偵錯資料庫應用程式

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

  2. 使用下列第一個範例區段中的程式碼建立 T-SQL 預存程序,並將其命名為 DeleteCurrency_T_SQL.。如需這項動作,或是這個程序中任何步驟的詳細資訊,請參閱 HOW TO:使用 SQL Server 專案類型開發

  3. 使用下列第二個範例區段的程式碼建立 SQL CLR 預存程序,並將其命名為 DeleteCurrency.cs。

  4. 使用下列第三個範例區段的程式碼建立 SQL CLR 預存程序,並將其命名為 DeleteCurrencyDriver。

  5. 在 [偵錯] 功能表上按一下 [啟動],以便將這些變更編譯和部署至 AdventureWorks 資料庫。

  6. 在每個預存程序中設定至少一個中斷點。無法從機器碼或 Managed 程式碼逐步執行至預存程序。

  7. 在 Visual Studio 中建立新的主控台專案。

  8. 將第四個範例中的程式碼貼到文字編輯器中。

  9. 在每個預存程序的呼叫前後放置中斷點。

  10. 按 F5 執行應用程式。

  11. 逐步執行不同的模組。

  12. 嘗試移除某些中斷點,以檢視在不同層和語言之間嘗試逐步執行的效果。

  13. 若要完成偵錯,請從 Visual Studio [偵錯] 功能表清除所有中斷點,然後按 F5。

範例

本節包含 T-SQL 預存程序的程式碼。

CREATE PROCEDURE dbo.DeleteCurrency_T_SQL
    (
        @CurrencyCode nvarchar(3)
    )
AS
    SET NOCOUNT ON
    DELETE Sales.Currency 
    WHERE CurrencyCode = @currencyCode 
    RETURN

這個程式碼包含從驅動程式預存程序呼叫之 SQL CLR 預存程序的程式碼。

using System;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
 
public partial class StoredProcedures
{
    [SqlProcedure]
    public static void DeleteCurrency(SqlString currencyCode)
    {
        string sCmd = "DELETE Sales.Currency WHERE CurrencyCode = '" + currencyCode.Value + "'";
        SqlConnection conn = new SqlConnection("Context Connection=True");
        conn.Open();
        SqlCommand  DeleteCurrencyCommand = new  SqlCommand( sCmd , conn);
        DeleteCurrencyCommand.ExecuteNonQuery();
    }
}

這個程式碼包含呼叫其他程序之 SQL CLR 驅動程式程序的程式碼。應用程式層會呼叫這個預存程序。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
 
public partial class StoredProcedures
{
    [SqlProcedure]
    public static void DeleteCurrencyDriver(SqlString CurrencyCode)
    {
        string sCommand = "DELETE Sales.Currency WHERE CurrencyCode = '" + CurrencyCode.Value + "'";
        SqlConnection conn = new SqlConnection("Context Connection=True");
        conn.Open();
        SqlCommand DeleteCurrencyCommand = new SqlCommand(sCommand, conn);
        DeleteCurrencyCommand.ExecuteNonQuery();
 
        // Now execute a T-SQL stored procedure.
        DeleteCurrencyCommand.CommandType = CommandType.StoredProcedure;
        DeleteCurrencyCommand.CommandText = "DeleteCurrency_T_SQL";
        // Fill the parameters collection based upon stored procedure.
        SqlParameter workParam = null;
        workParam = DeleteCurrencyCommand.Parameters.Add("@CurrencyCode", SqlDbType.NChar, 3);
        DeleteCurrencyCommand.Parameters["@CurrencyCode"].Value = "ESC";
        try { DeleteCurrencyCommand.ExecuteNonQuery(); }
        catch { }
 
        // Now execute a CLR stored procedure.
        DeleteCurrencyCommand.CommandText = "DeleteCurrency";
        try { DeleteCurrencyCommand.ExecuteNonQuery(); }
        catch { }
    }
};

這個程式碼包含呼叫驅動程式預存程序的應用程式碼,以及直接呼叫 T-SQL 和 SQL CLR 預存程序的應用程式碼。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
            builder.DataSource = <server>;
            builder.IntegratedSecurity = true;
            builder.InitialCatalog = <database>;
 
            SqlConnection SqlConnection1 = new SqlConnection(builder.ConnectionString);
            SqlConnection1.Open();
 
            SqlCommand procCommand = new SqlCommand();
 
            procCommand.CommandText = "DeleteCurrencyDriver";
            procCommand.CommandType = CommandType.StoredProcedure;
            procCommand.Connection = SqlConnection1;
            // Fill parameters collection for the stored procedure.
            SqlParameter workParam = null;
            workParam = procCommand.Parameters.Add("@CurrencyCode", SqlDbType.NChar, 3);
            procCommand.Parameters["@CurrencyCode"].Value = "ESC";
            
            try { procCommand.ExecuteNonQuery(); }
            catch (SqlException e) { DumpException(e); }
 
            procCommand.CommandText = "DeleteCurrency";
            try { procCommand.ExecuteNonQuery(); }
            catch (SqlException e) { DumpException(e); }
 
            procCommand.CommandText = "DeleteCurrency_T_SQL";
            try { procCommand.ExecuteNonQuery(); }
            catch (SqlException e) { DumpException(e); }
 
            SqlConnection1.Close();
        }
        static void DumpException(SqlException e)
       {
            string errorMessages = "";
            for (int i = 0; i < e.Errors.Count; i++)
           {
                errorMessages += "Index #" + i + "\n" +
                       "Message: " + e.Errors[i].Message + "\n" +
                       "LineNumber: " + e.Errors[i].LineNumber + "\n" +
                       "Source: " + e.Errors[i].Source + "\n" +
                       "Procedure: " + e.Errors[i].Procedure + "\n";
            }
            System.Diagnostics.EventLog log = new System.Diagnostics.EventLog();
            log.Source = "My Application";
            log.WriteEntry(errorMessages);
            Console.WriteLine("An exception occurred. Please contact your system administrator.");
        }
    }
}

請參閱

工作

HOW TO:啟用專案的 SQL 偵錯

HOW TO:啟用多層偵錯

HOW TO:啟用連接的 CLR 偵錯

HOW TO:啟用 SQL Server 2005 偵錯