如何:调试多层数据库应用程序

更新:2007 年 11 月

本主题适用于:

版本

Visual Basic

C#

C++

Web Developer

速成版

主题不适用 主题不适用 主题不适用 主题不适用

标准版

主题不适用 主题不适用 主题不适用 主题不适用

专业团队版

主题适用 主题适用 主题适用 主题适用

表格图例:

主题适用

适用

主题不适用

不适用

主题适用,但命令默认情况下隐藏

默认情况下隐藏的一条或多条命令。

本主题包含演示如何调试多层应用程序的示例代码,并介绍从驻留在客户端或中间层应用程序中的应用程序代码进入在 SQL Server 2005 中运行的数据库对象的代码所需的调试步骤。

应用程序层与数据库层之间的转换要求在目标层中设置断点;否则,在尝试单步执行目标层时,只执行代码而不会停止。但是数据库层内部的 T-SQL 代码和 SQL CLR 代码之间的转换不需要断点就可以在这两者之间单步执行。

下面示例使用 AdventureWorks 数据库,并在不同层及不同语言之间来回执行单步调试。该示例旨在阐释这些转换,显然不是实际的业务方案。

示例调用三个存储过程:

  • DeleteCurrency 是一个 SQL CLR 存储过程,它删除具有给定货币代码的货币。

  • DeleteCurrency_T_SQL 执行同一操作,但是它是用 T-SQL 编写的。

  • DeleteCurrencyDriver 调用上述两个存储过程,它有一个输入参数,该参数指定要删除的货币的代码。

应用程序代码调用这三个存储过程,并传入货币代码参数。从两种不同的上下文(即从 DeleteCurrencyDriver 和直接从应用程序)调用两个“非驱动程序”存储过程。在第一个上下文中,可以从 DeleteCurrencyDriver 单步进入其他两个存储过程。从应用程序调用它们时,不能直接单步进入它们,而必须在存储过程中设置断点。

调试数据库应用程序

  1. 在一个新的 SQL Server 项目中,建立一个到 AdventureWorks 数据库的连接。有关更多信息,请参见如何:连接到数据库

  2. 使用下面第一个示例部分中的代码创建 T-SQL 存储过程,并将其命名为 DeleteCurrency_T_SQL。有关此步骤或此过程中任何步骤的更多信息,请参见 如何:使用 SQL Server 项目类型进行开发

  3. 使用下面第二个示例部分中的代码创建一个 SQL CLR 存储过程,并将其命名为 DeleteCurrency.cs。

  4. 使用下面第三个示例部分中的代码创建一个 SQL CLR 存储过程,并将其命名为 DeleteCurrencyDriver。

  5. 在“调试”菜单上单击“开始”,将这些更改编译并部署到 AdventureWorks 数据库中。

  6. 在每个存储过程中至少设置一个断点。从本机代码或托管代码无法进入并单步执行存储过程。

  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.");
        }
    }
}

请参见

任务

如何:为项目启用 SQL 调试

如何:启用多层调试

如何:为连接启用 CLR 调试

如何:启用 SQL Server 2005 调试