Практическое руководство. Отладка многоуровневого приложения базы данных
Обновлен: Ноябрь 2007
Этот раздел применим к:
Выпуск |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Экспресс-выпуск |
||||
Standard |
||||
Pro и Team |
Условные обозначения таблицы:
Применяется |
|
Не применяется |
|
Команда или команды, скрытые по умолчанию. |
В данном разделе приводится пример кода, в котором показан процесс отладки многоуровневого приложения и описаны шаги, необходимые для выполнения отладки из кода приложения, находящегося в клиенте или многоуровневом приложении, в код для объекта базы данных, выполняющегося внутри объекта SQL Server 2005.
Для переходов между уровнями приложения и базы данных необходимо наличие точки останова в целевом уровне. В противном случае код просто выполняется без остановки при попытке входа в уровень. Но для перехода между T-SQL и кодом SQL CLR в пределах уровня базы данных не требуется наличие точек останова для включения пошаговой отладки.
В следующем примере используется база данных AdventureWorks и показано перемещение вперед и назад между различными уровнями и языками. Цель примера — проиллюстрировать эти перемещения. Пример не является настоящим бизнес-сценарием.
Вызываются три хранимые процедуры:
Процедура DeleteCurrency — это хранимая процедура SQL CLR, с помощью которой удаляется валюта с указанным кодом валюты.
Процедура DeleteCurrency_T_SQL выполняет аналогичное действие, но записывается в T-SQL.
Запуск процедуры DeleteCurrencyDriver вызывает две предыдущие хранимые процедуры с входным параметром, указывающим код валюты, предназначенной для удаления.
Код приложения вызывает все три хранимые процедуры, передавая параметр кода валюты. Две хранимые процедуры, "не являющиеся драйверами", вызываются из двух разных контекстов: из объекта DeleteCurrencyDriver и напрямую из приложения. В первом контексте можно выполнить переход из объекта DeleteCurrencyDriver в две другие хранимые процедуры. При вызове процедур из приложения будет невозможно перейти в них напрямую. Для этого следует создать точки останова внутри хранимых процедур.
Отладка приложения базы данных
В новом проекте SQL Server установите соединение с базой данных AdventureWorks. Дополнительные сведения см. в разделе Практическое руководство. Подключение к базе данных.
Создайте хранимую процедуру T-SQL с использованием кода из первого раздела примера, указанного ниже, и назовите ее DeleteCurrency_T_SQL.Дополнительные сведения об этом процессе или любых других шагах данной процедуры см. в разделе Практическое руководство. Разработка с помощью типа проекта SQL Server.
Создайте хранимую процедуру SQL CLR с использованием кода из второго раздела примера, указанного ниже, и назовите ее DeleteCurrency.cs.
Создайте хранимую процедуру SQL CLR с использованием кода из третьего раздела примера, указанного ниже, и назовите ее DeleteCurrencyDriver.
В меню Отладка выберите пункт Пуск для компиляции и развертывания внесенных в базу данных AdventureWorks изменений.
Создайте не менее одной точки останова для каждой хранимой процедуры. Переход из машинного или управляемого кода в хранимую процедуру не сработает.
Создайте в объекте Visual Studio новый консольный проект.
Вставьте код из четвертого примера в текстовый редактор.
Разместите точки останова перед и после каждого вызова в хранимой процедуре.
Запустите приложение, нажав клавишу F5.
Перейдите к другим модулям.
Постарайтесь удалить некоторые из точек останова, чтобы увидеть эффект перехода между различными уровнями и языками.
Для завершения отладки удалите все точки останова из меню объекта 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