這個主題適用於:
Visual Studio Ultimate |
Visual Studio Premium |
Visual Studio Professional |
Visual Studio Express |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
本主題包含的範本程式碼示範如何偵錯多層應用程式,並且說明要從用戶端或中層應用程式中的應用程式程式碼逐步偵錯至資料庫物件 (於開頭為 SQL Server 2005 的 SQL Server 執行個體中執行) 中的 Transact-SQL 程式碼,需要哪些步驟。
若要在應用程式層與資料層之間轉換,目標層中必須要有中斷點,否則,程式碼會一直執行,而不會在您嘗試逐步執行至該層時停止。不過,若要在 Transact-SQL 與儲存於資料庫層的 SQL CLR 程式碼之間轉換,則不需要中斷點也能在兩者之間逐步執行。
下列範例使用 C# 主控台應用程式、一個名為 Currency 的 SQL Server 資料庫資料表,以及兩個預存程序,在 C# 和 Transact-SQL 之間來回逐步執行。此範例的用意在於示範這些轉換,而且很明顯不是實際的商務案例。
呼叫兩個預存程序:
DeleteCurrency 是 Transact-SQL 預存程序,會刪除含有指定貨幣代碼的貨幣。
DeleteCurrencyDriver 也是 Transact-SQL 預存程序。它會呼叫上一個預存程序,該預存程序所包含的輸入參數會指定要刪除的貨幣代碼。
應用程式程式碼會傳入貨幣代碼參數,以呼叫這兩個預存程序。在兩種內容中會呼叫「非驅動程式」(non-driver) 預存程序:從 DeleteCurrencyDriver 呼叫,以及直接從應用程式呼叫。在第一種內容中,按一下 [逐步執行] 按鈕,您就能從 DeleteCurrencyDriver 逐步執行到另一個預存程序。從應用程式呼叫上述預存程序時,您無法直接逐步執行至這些預存程序,而且必須在預存程序中設定中斷點。
建立本示範所用的 Transact-SQL 資料庫物件
在任一 SQL Server 2005 (含) 以後的資料庫中,使用第一個範例中的程式碼建立 Currency 資料表和兩個預存程序。
開啟 Visual Studio 中的 Transact-SQL 編輯器,並連接至您可以在本示範中使用的資料庫。如需詳細資訊,請參閱 HOW TO:啟動 Transact-SQL 編輯器和 HOW TO:在 Transact-SQL 編輯器中連接至資料庫。
複製第一個範例中的 Transact-SQL 程式碼,並貼至 Transact-SQL 編輯器中。
以適當的資料庫名稱取代 <database>,然後按一下 [Transact-SQL 編輯器] 工具列中的 [執行 SQL]。
如果您先前已經在 SQL Server 資料庫或伺服器專案內容中開啟 Transact-SQL 編輯器,請先關閉該專案再繼續進行。否則,您可以讓 Transact-SQL 編輯器保持開啟並繼續進行。
預備伺服器總管以進行多層偵錯
確定您的電腦已啟用 Transact-SQL 偵錯。如需詳細資訊,請參閱 HOW TO:啟用 Transact-SQL 偵錯。
開啟 [檢視] 功能表並按一下 [伺服器總管],然後按一下 [伺服器總管]。
在 [伺服器總管] 中,以滑鼠右鍵按一下 [資料連接] 並選取 [加入連接],以建立新的資料連接。這樣會啟動 [加入連接] 對話方塊。
與您建立 Currency 資料表所在的資料庫建立連接。連接使用的登入必須是 sysadmin 固定伺服器角色的成員之一。如需詳細資訊,請參閱 HOW TO:使用伺服器總管連接到資料庫。
建立新的資料連接後,請在 [資料連接] 節點下找到該資料連接。
以滑鼠右鍵按一下新的資料連接,然後按一下 [應用程式偵錯]。這樣會啟用在連接中指定的資料庫進行多層偵錯。
預備 C# 主控台應用程式以進行多層偵錯
在您預備 [伺服器總管] 的同一個 Visual Studio 執行個體中,預備一個會執行 DeleteCurrencyDriver 和 DeleteCurrency 預存程序的 C# 主控台應用程式。
開啟 [檔案] 功能表並按一下 [新增專案],開啟新的 C# 主控台應用程式。
複製第二個範例中的 C# 程式碼,並以此取代 Program.cs 檔案中由專案建立的所有程式碼。
在主控台應用程式屬性中的 [偵錯] 索引標籤上,勾選 [啟用 SQL Server 偵錯]。這樣會啟用主控台應用程式的多層偵錯。如需詳細資訊,請參閱 HOW TO:針對 C++、Visual Basic 或 C# 專案啟用 Transact-SQL 偵錯。
偵錯多層主控台應用程式
在 C# 程式碼 (Program.cs 檔案) 中,將中斷點放在每個預存程式呼叫的前後。
將中斷點放入您的預存程序中。注意:您不能從 C# 程式碼逐步執行至 Transact-SQL 程式碼,但可以在 SQL Server 資料庫專案之間逐步執行。
在 [伺服器總管] 中,於新的資料連接下找到新的預存程序。
以滑鼠右鍵按一下 [DeleteCurrency] 預存程序,並且按一下 [開啟]。這樣會啟動 Transact-SQL 編輯器視窗,其中顯示 DeleteCurrency 預存程序。按一下編輯器左邊的灰色列,在 SET NOCOUNT ON 行上設定中斷點。
以滑鼠右鍵按一下 [DeleteCurrencyDriver] 預存程序,並按一下 [開啟]。這樣會啟動 Transact-SQL 編輯器視窗,其中顯示 DeleteCurrencyDriver 預存程序。按一下編輯器左邊的灰色列,在 SET NOCOUNT ON 行上設定中斷點。
按 F5 鍵執行應用程式。
逐步執行不同的模組。
嘗試移除部分中斷點,看看嘗試在不同層與語言之間逐步執行的作用。
若要完成偵錯,請清除 [Visual Studio 偵錯] 功能表中的所有中斷點,再按 F5 鍵。
範例
本節包含的 Transact-SQL 程式碼可建立 Currency 資料表和兩個預存程序:DeleteCurrency 和 DeleteCurrencyDriver。 請以適當的資料庫名稱取代 <database>。
USE <database>
GO
CREATE TABLE Currency
(CurrencyCode nvarchar(1))
INSERT Currency
VALUES (N'A'),(N'B'),(N'C'),(N'D')
SELECT * FROM Currency
GO
CREATE PROCEDURE dbo.DeleteCurrency
(
@CurrencyCode nvarchar(3)
)
AS
SET NOCOUNT ON
DELETE Currency
WHERE CurrencyCode = @currencyCode
RETURN
GO
CREATE PROCEDURE dbo.DeleteCurrencyDriver
(
@CurrencyCode nvarchar(3)
)
AS
SET NOCOUNT ON
EXECUTE DeleteCurrency @CurrencyCode
RETURN
GO
本節包含主控台應用程式的 C# 程式碼,該程式碼會呼叫 DeleteCurrencyDriver 和 DeleteCurrency 預存程序。以執行個體和 Currency 資料表所在之資料庫的名稱分別取代 <server> 和 <database>。
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, 1);
procCommand.Parameters["@CurrencyCode"].Value = "B";
try { procCommand.ExecuteNonQuery(); }
catch (SqlException e) { Console.WriteLine(e.Message); }
//Execute DeleteCurrency stored procedure directly
procCommand.CommandText = "DeleteCurrency";
try { procCommand.ExecuteNonQuery(); }
catch (SqlException e) { Console.WriteLine(e.Message); }
SqlConnection1.Close();
Console.WriteLine("Press any key to close...");
Console.Read();
}
}
}
.gif)
.gif)