Cómo: Depurar una aplicación de base de datos de varios niveles

Actualización: noviembre 2007

Este tema se aplica a:

Edición

Visual Basic

C#

C++

Web Developer

Express

Standard

Pro y Team

Leyenda de la tabla:

Se aplica

No procede

Comando o comandos ocultos de manera predeterminada.

Este tema contiene código de ejemplo que muestra cómo depurar una aplicación de varios niveles y describe los pasos necesarios para depurar desde el código de una aplicación que reside en un cliente o nivel medio de una aplicación hasta el código de un objeto de base de datos que se ejecuta dentro de SQL Server 2005.

Las transiciones entre el nivel de aplicación y el nivel de base de datos requieren de un punto de interrupción en el nivel de destino; de lo contrario el código se ejecutará sin interrupción cuando intente la ejecución paso a paso en dicho nivel. No obstante, las transiciones entre código T-SQL y SQL CLR en el nivel de base de datos no requieren puntos de interrupción que habiliten la ejecución paso a paso entre ellos.

El ejemplo siguiente utiliza la base de datos AdventureWorks y avanza de un lado a otro entre los diferentes niveles y lenguajes. El objetivo del ejemplo es ilustrar estas transiciones y está claro que el ejemplo no trata de ningún escenario de negocios real.

Se llama a tres procedimientos almacenados:

  • DeleteCurrency es un procedimiento almacenado de SQL CLR que elimina una moneda con un código de moneda determinado.

  • DeleteCurrency_T_SQL realiza la misma acción, pero está escrito en T-SQL.

  • DeleteCurrencyDriver llama a los dos procedimientos almacenados anteriores con un parámetro de entrada que especifica el código de moneda para eliminar.

El código de aplicación llama a los tres procedimientos almacenados, transmitiendo un parámetro de código de moneda. Se llama a los dos procedimientos almacenados, que no son de controlador, desde dos contextos diferentes: DeleteCurrencyDriver y directamente desde la aplicación. En el primer contexto, podrá pasar de DeleteCurrencyDriver a los otros dos procedimientos almacenados. Cuando se les llame desde la aplicación, no podrá recorrerlos paso a paso directamente y tendrá que establecer puntos de interrupción en los procedimientos almacenados.

Depurar una aplicación de base de datos

  1. En un nuevo proyecto de SQL Server, establezca una conexión a la base de datos AdventureWorks. Para obtener más información, vea Cómo: Conectarse a una base de datos.

  2. Cree un nuevo procedimiento almacenado de T-SQL utilizando el código de la primera parte del ejemplo siguiente y asígnele el nombre DeleteCurrency_T_SQL.Para obtener más información sobre éste u otros pasos del procedimiento, vea Cómo: Desarrollar con el tipo de proyecto de SQL Server.

  3. Cree un procedimiento almacenado de SQL CLR utilizando la segunda parte del ejemplo siguiente y asígnele el nombre DeleteCurrency.cs.

  4. Cree un procedimiento almacenado de SQL CLR utilizando la tercera parte del ejemplo siguiente y asígnele el nombre DeleteCurrencyDriver.

  5. En el menú Depurar, haga clic en Iniciar para compilar e implementar estos cambios en la base de datos AdventureWorks.

  6. Establezca al menos un punto de interrupción en cada procedimiento almacenado. No podrá desplazarse desde código nativo o administrado hasta un procedimiento almacenado.

  7. Cree un nuevo proyecto de consola en Visual Studio.

  8. Pegue el código de la cuarta parte del ejemplo en el editor de texto.

  9. Coloque los puntos de interrupción antes y después de cada llamada a un procedimiento almacenado.

  10. Presione F5 para ejecutar la aplicación.

  11. Ejecute paso a paso los diferentes módulos.

  12. Pruebe a quitar algunos de los puntos de interrupción para ver el efecto que se produce al intentar avanzar entre los diferentes niveles y lenguajes.

  13. Para finalizar la depuración, borre todos los puntos de interrupción del menú Depurar de Visual Studio y presione F5.

Ejemplo

Esta sección contiene el código para el procedimiento almacenado de T-SQL.

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

Este código contiene el código para el procedimiento almacenado de SQL CLR al que llama un procedimiento almacenado de controlador.

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

Este código contiene el código para el procedimiento de controlador de SQL CLR que llama a otros procedimientos. Se llama a este procedimiento almacenado desde el nivel de aplicación.

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

Este código contiene el código de aplicación que llama al procedimiento almacenado de controlador y, también, directamente a los procedimientos almacenados de T-SQL y 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.");
        }
    }
}

Vea también

Tareas

Cómo: Habilitar la depuración SQL para un proyecto

Cómo: Habilitar la depuración de varios niveles

Cómo: Habilitar la depuración CLR para una conexión

Cómo: Habilitar una depuración de SQL Server 2005