Freigeben über


Gewusst wie: Debuggen einer Datenbankanwendung mit mehreren Ebenen

Aktualisiert: November 2007

Dieses Thema gilt für folgende Anwendungsbereiche:

Edition

Visual Basic

C#

C++

Web Developer

Express

Standard

Pro und Team

Tabellenlegende:

Vorhanden

Nicht vorhanden

Befehl oder Befehle, die standardmäßig ausgeblendet sind.

Dieses Thema enthält Beispielcode, der das Debuggen einer Anwendung mit mehreren Ebenen veranschaulicht. Weiterhin werden die Schritte beschrieben, die erforderlich sind, um von Anwendungscode in einem Client oder einer Anwendung auf der mittleren Ebene aus den Code eines Datenbankobjekts zu debuggen, das in SQL Server 2005 ausgeführt wird.

Für den Übergang von der Anwendungsebene zur Datenbankebene ist ein Haltepunkt in der Zielebene erforderlich. Andernfalls wird der Code ausgeführt, ohne anzuhalten, wenn Sie versuchen, in die Ebene zu wechseln. Für Übergänge zwischen T-SQL-Code und SQL/CLR-Code innerhalb der Datenbankebene ist jedoch kein Haltepunkt erforderlich, um das Wechseln zu ermöglichen.

Im Beispiel wird die Datenbank AdventureWorks verwendet, und es wird zwischen den verschiedenen Ebenen und Sprachen gewechselt. Der Sinn des Beispiels besteht darin, diese Übergänge zu veranschaulichen. Es handelt sich dabei nicht um ein reales Geschäftsszenario.

Es werden drei gespeicherte Prozeduren aufgerufen:

  • DeleteCurrency ist eine gespeicherte SQL/CLR-Prozedur, die eine Währung mit einem bestimmten Währungscode löscht.

  • DeleteCurrency_T_SQL bewirkt dasselbe, ist jedoch in T-SQL geschrieben.

  • DeleteCurrencyDriver ruft die beiden vorangegangenen gespeicherten Prozeduren mit einem Eingabeparameter auf, der den zu löschenden Währungscode angibt.

Im Anwendungscode werden alle drei gespeicherten Prozeduren aufgerufen, wobei ein Währungscodeparameter übergeben wird. Die beiden gespeicherten "Nicht-Treiber-Prozeduren" werden aus zwei verschiedenen Kontexten aufgerufen: aus DeleteCurrencyDriver und direkt aus der Anwendung. Im ersten Kontext können Sie von DeleteCurrencyDriver die beiden anderen gespeicherten Prozeduren in Einzelschritten durchlaufen. Beim Aufruf aus der Anwendung können Sie sie nicht direkt in Einzelschritten durchlaufen. Sie müssen stattdessen innerhalb der gespeicherten Prozeduren Haltepunkte festgelegen.

Debuggen einer Datenbankanwendung

  1. Stellen Sie in einem neuen SQL Server-Projekt eine Verbindung zur Datenbank AdventureWorks her. Weitere Informationen finden Sie unter Gewusst wie: Herstellen einer Verbindung zu einer Datenbank.

  2. Erstellen Sie mit dem Code des ersten Beispielabschnitts (siehe unten) eine gespeicherte T-SQL-Prozedur mit dem Namen DeleteCurrency_T_SQL.Weitere Informationen dazu und zu den einzelnen Schritten dieser Prozedur finden Sie unter Gewusst wie: Entwickeln mit dem SQL Server-Projekttyp.

  3. Erstellen Sie mit dem Code aus dem zweiten Beispielabschnitt unten eine gespeicherte SQL/CLR-Prozedur mit dem Namen DeleteCurrency.cs.

  4. Erstellen Sie mit dem Code aus dem dritten Beispielabschnitt unten eine gespeicherte SQL/CLR-Prozedur mit dem Namen DeleteCurrencyDriver.

  5. Klicken Sie im Menü Debuggen auf Starten, um diese Änderungen für die Datenbank AdventureWorks zu kompilieren und bereitzustellen.

  6. Legen Sie in jeder gespeicherten Prozedur mindestens einen Haltepunkt fest. Das Wechseln aus systemeigenem oder verwaltetem Code in eine gespeicherte Prozedur ist nicht möglich.

  7. Erstellen Sie in Visual Studio ein neues Konsolenprojekt.

  8. Fügen Sie den Code aus dem vierten Beispiel in den Text-Editor ein.

  9. Platzieren Sie vor und nach jedem Aufruf einer gespeicherten Prozedur einen Haltepunkt.

  10. Führen Sie die Anwendung aus, indem Sie F5 drücken.

  11. Durchlaufen Sie die verschiedenen Module.

  12. Entfernen Sie versuchsweise einige Haltepunkte, um zu beobachten, welche Auswirkungen der Wechsel zwischen verschiedenen Ebenen und Sprachen hat.

  13. Wenn Sie das Debuggen beenden möchten, löschen Sie in Visual Studio über das Menü Debuggen alle Haltepunkte, und drücken Sie F5.

Beispiel

Dieser Abschnitt enthält den Code für die gespeicherte T-SQL-Prozedur.

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

Dieses Codebeispiel enthält den Code für die gespeicherte SQL/CLR-Prozedur, die von einer gespeicherten Treiberprozedur aufgerufen wird.

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();
    }
}

Dieses Codebeispiel enthält den Code für die SQL/CLR-Treiberprozedur, die die anderen Prozeduren aufruft. Diese gespeicherte Prozedur wird in der Anwendungsebene aufgerufen.

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 { }
    }
};

Dieses Codebeispiel enthält den Anwendungscode, der sowohl die gespeicherte Treiberprozedur als auch die gespeicherten T-SQL- und SQL/CLR-Prozeduren direkt aufruft.

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

Siehe auch

Aufgaben

Gewusst wie: Aktivieren des SQL-Debuggens für ein Projekt

Gewusst wie: Aktivieren von Debuggen mit mehreren Ebenen

Gewusst wie: Aktivieren von CLR-Debuggen für eine Verbindung

Gewusst wie: Aktivieren von SQL Server 2005-Debuggen