首先查看一下 ADO.NET 2.0 提供用來(lái)創(chuàng)建 SQL Server 服務(wù)器端對(duì)象的相關(guān)類。
11.2.1 System.Data.SqlServer 命名空間
當(dāng)用 .NET 開(kāi)發(fā) SQL Server 的內(nèi)部對(duì)象時(shí),最常使用的命名空間將會(huì)是存在 Sqlaccess.dll 程序文件內(nèi)的 System.Data.SqlServer。若你曾經(jīng)用 ADO.NET 開(kāi)發(fā)數(shù)據(jù)庫(kù)的應(yīng)用程序,則部分對(duì)象是相通的。例如 SqlConnection、SqlCommand 等,微軟的開(kāi)發(fā)小組盡量讓程序設(shè)計(jì)師在 SQL Server 內(nèi)訪問(wèn)數(shù)據(jù)與在外部訪問(wèn)數(shù)據(jù)的程序編寫方式相似,而不需要熟悉兩套開(kāi)發(fā)模式。以下稍微解釋這些對(duì)象:
SqlContext:SqlContext 類讓你可以取得 SQL Server 內(nèi)部調(diào)用者的執(zhí)行環(huán)境(Context),主要是取得 SqlPipe 類實(shí)例,用此返回結(jié)果給前端調(diào)用該數(shù)據(jù)庫(kù)對(duì)象的應(yīng)用程序,或是 SqlTriggerContext 以提供編寫觸發(fā)器(Trigger)的相關(guān)數(shù)據(jù)。SqlContext 類在讓我們所編寫的程序集與 SQL Server 進(jìn)行溝通時(shí)顯得非常重要。使用該類的程序范例如程序代碼列表11-1所示:
程序代碼列表11-1 通過(guò) SqlContext 取得用戶當(dāng)前的執(zhí)行環(huán)境
Using cnn As New SqlConnection("Context Connection=true")
Using sqlCmd As New SqlCommand
'因?yàn)?Product 數(shù)據(jù)表屬于不同的 Schema,所以需要加上 Schema 名稱
cnn.Open()
sqlCmd.Connection = cnn
sqlCmd.CommandText = "SELECT ProductNumber FROM Production.Product"
Dim sqlRead As SqlDataReader = sqlCmd.ExecuteReader()
'因?yàn)槭谴鎯?chǔ)過(guò)程,要通過(guò) SqlPipe 將運(yùn)行結(jié)果接回原來(lái) SQL Server 的輸出
Dim sqlP As SqlPipe = SqlContext.Pipe
sqlP.Send(sqlRead)
End Using
End Using
程序代碼列表11-1 僅是簡(jiǎn)單地取得 Production.Product 數(shù)據(jù)表內(nèi)的 ProductNumber 字段,然后直接返回給前端。由于被調(diào)用的對(duì)象是在用戶已經(jīng)取得的連接環(huán)境內(nèi)執(zhí)行,若要傳遞數(shù)據(jù)給用戶,就需要通過(guò)程序代碼列表 11-1 的方式引用 SqlContext 類的 Pipe 屬性,取得 SqlPipe 對(duì)象實(shí)例后,再通過(guò) Send 方法將結(jié)果返回。
SqlConnection:讓我們所編寫的程序取得對(duì)程序集實(shí)例被 SQL Server 外部的前端應(yīng)用程序調(diào)用時(shí),該應(yīng)用程序所在的數(shù)據(jù)庫(kù)連接相關(guān)設(shè)置。這些連接設(shè)置并不是由我們用 .NET 所編寫的存儲(chǔ)過(guò)程或用戶自定義函數(shù)的對(duì)象決定的,被調(diào)用的數(shù)據(jù)庫(kù)內(nèi)部對(duì)象需要與外部應(yīng)用程序使用相同的連接環(huán)境??梢杂靡韵碌某绦蛲ㄟ^(guò)連接字符串設(shè)置如下,而通過(guò)這條連接再執(zhí)行其他的 SQL 語(yǔ)法:
Using cnn As New SqlConnection("Context Connection=true")
SqlCommand:讓你傳送 T-SQL 命令到數(shù)據(jù)庫(kù)服務(wù)器,參照前述程序代碼列表 11-1 的范例,可以依照一般方式創(chuàng)建 SqlCommand 對(duì)象實(shí)例,并通過(guò) SqlConnection 實(shí)例來(lái)執(zhí)行取得產(chǎn)品編號(hào)的 T-SQL 語(yǔ)法。
SqlParameter:用以設(shè)置與訪問(wèn) SqlCommand 對(duì)象內(nèi)傳遞的參數(shù)。范例程序如程序代碼列表11-2所示:
程序代碼列表 11-2 通過(guò) SqlCommand 和 SqlParameter 對(duì)象搭配SHA1 哈希算法為密碼編碼
_
Public Shared Sub WriteHashedPassword(ByVal UserName As String, ByVal Password As String)
'將賬號(hào)/密碼經(jīng)過(guò) Sha1 Hash 口算法換算后,再存入數(shù)據(jù)表
Try
Using cnn As New SqlConnection("Context Connection=true")
cnn.Open()
Using sqlCmd As New SqlCommand
Dim sh1 As New SHA1Managed
Dim uEncode As New UnicodeEncoding
'將密碼以 SHA1 計(jì)算哈希值,再以 Base64 編碼。
Dim txtBytes As Byte() = uEncode.GetBytes(Password)
Dim hashedPassword As Byte() = sh1.ComputeHash(txtBytes)
Dim strHash As String = Convert.ToBase64String(hashedPassword)
Dim dml As String = "INSERT NamePass VALUES(@UserName,@HashAsString)"
With sqlCmd
.Connection = cnn
.CommandText = dml
'通過(guò) SqlParameter 對(duì)象設(shè)置 SqlCommand 對(duì)象所包含 T-SQL 語(yǔ)法
'需要的參數(shù)
.Parameters.Add(New SqlParameter("@UserName", SqlDbType.NVarChar, 50))
.Parameters(0).Value = UserName
.Parameters.Add(New SqlParameter("@HashAsString", SqlDbType.NVarChar, 100))
.Parameters(1).Value = strHash
sqlCmd.ExecuteNonQuery()
End With
End Using
cnn.Close()
End Using
Catch ex As Exception
Dim fs As New FileStream("C:\YukonCLR.log", FileMode.OpenOrCreate, FileAccess.Write)
Dim sw As New StreamWriter(fs)
sw.WriteLine(ex.ToString())
sw.Close()
End Try
End Sub
常常有朋友詢問(wèn)如何將用戶輸入的密碼通過(guò)哈希(Hash)算法計(jì)算過(guò)后再放入數(shù)據(jù)庫(kù)中,在以往筆者只能建議在應(yīng)用程序端編寫,現(xiàn)在相同的語(yǔ)法可以寫成存儲(chǔ)過(guò)程保存在 SQL Server 內(nèi),如程序代碼列表11-2 所示。而一般的用戶只需要簡(jiǎn)單地調(diào)用存儲(chǔ)過(guò)程,就可以將密碼通過(guò) .NET Framework 提供的 SHA1 哈希算法編碼后,再存入到數(shù)據(jù)表。
SqlPipe:將執(zhí)行結(jié)果或信息送回前端應(yīng)用程序,程序范例可以參照程序代碼列表 11-1 最后兩行。如果前端是通過(guò) ADO 或 ADO.NET 對(duì)象訪問(wèn) SQL Server,而我們編寫的對(duì)象返回文字信息,則會(huì)被前端視為 Connection 對(duì)象的 InfoMessage 事件,范例如下。你也可以返回單一條記錄或是整個(gè)數(shù)據(jù)集合。
Dim pipe As SqlPipe = SqlContext.Pipe
‘傳送信息
pipe.Send(“完成事務(wù)”)
SqlDataReader:通過(guò) SQL Server 提供的只能向前移動(dòng)(forward-only)、只讀(read-only)游標(biāo)(Cursor)來(lái)訪問(wèn)數(shù)據(jù)。
Dim sdr As SqlDataReader = cmd.ExecuteReader()
While sdr.Read()
Debug.WriteLine(sdr("EmployeeID") & "-" & sdr(1))
End While
sdr.Close()
上述范例程序中通過(guò) Read 函數(shù)逐條讀出數(shù)據(jù),直到數(shù)據(jù)記錄讀取完畢,Read 函數(shù)會(huì)返回 false,我們據(jù)此退出循環(huán)。
System.Transactions.Transaction:.NET Framework2.0新增了 System.Transactions 命名空間,在其內(nèi)可提供新的事務(wù)管理架構(gòu)與功能。若只就此處的 SQL Server 內(nèi)部對(duì)象而言,你不太需要管理,因?yàn)楫?dāng)通過(guò) SqlConnection 取得對(duì)象執(zhí)行環(huán)境的連接時(shí),若該連接已經(jīng)有事務(wù),則會(huì)自動(dòng)加入,你可以通過(guò) Transaction 的靜態(tài)屬性 Current 取得當(dāng)前的事務(wù)狀況,以此完成或恢復(fù)事務(wù)。范例程序如下:
Catch ex As Exception
Transaction.Current.Rollback
約略看完 ADO.NET 2.0 與創(chuàng)建 SQL Server 2005 對(duì)象相關(guān)的類后,我們接著來(lái)看一下,如何通過(guò) Visual Studio 2005 建構(gòu)對(duì)象。
11.2.2 通過(guò)Visual Studio 2005創(chuàng)建供SQL Server 2005用的Assembly
首先在 Visual Studio 2005 新建一個(gè)新的項(xiàng)目,類型為“SQL Server Project”,
由于需要 Visual Studio 2005 集成開(kāi)發(fā)環(huán)境幫我們部署已開(kāi)發(fā)好的數(shù)據(jù)庫(kù)對(duì)象到 SQL Server 2005 實(shí)例的數(shù)據(jù)庫(kù)內(nèi),所以相關(guān)的連接設(shè)置必須正確。若在圖11-3 設(shè)置錯(cuò)誤,可以在進(jìn)入項(xiàng)目后,在“解決方案資源管理器”窗口內(nèi)以鼠標(biāo)右鍵點(diǎn)選項(xiàng)目名稱,通過(guò)快捷選項(xiàng)“屬性(Properties)”,或是鼠標(biāo)雙擊項(xiàng)目下的“My Project”節(jié)點(diǎn),另外,Visual Basic.NET 默認(rèn)的根命名空間(Root Namespace)和程序集名稱(Assembly Name)將會(huì)與項(xiàng)目名稱相同,在部署程序集到 SQL Server 2005 時(shí)將會(huì)用到這兩個(gè)名稱。若你想更改根命名空間或程序集名稱可以進(jìn)入“應(yīng)用程序(Application)”頁(yè)簽修改
接著在Visual Studio 2005的項(xiàng)目?jī)?nèi)選取工具選單上的“項(xiàng)目”-“添加新項(xiàng)目”,打開(kāi)如圖11-6的對(duì)話框,在對(duì)話框內(nèi)選擇“Stored Procedure”項(xiàng)目,或于“解決方案資源管理器”內(nèi)使用快捷選項(xiàng),選擇“新建項(xiàng)目(New Item)”亦可。
在圖11-6 中填入適當(dāng)名稱后,點(diǎn)選“添加(Add)”按鈕,以添加定義“Stored Procedure”的模板。
在此,我們創(chuàng)建一個(gè)存儲(chǔ)過(guò)程,內(nèi)容如上文程序代碼列表 11-2 的定義。
在各對(duì)象前可以加上 System.Data.Sql 命名空間下所提供的一組 Attribute 來(lái)告知該函數(shù)的用途,同時(shí)可以通過(guò)該 Attribute 的 name 屬性(Property)來(lái)告知該函數(shù)或類型創(chuàng)建到 SQL Server 內(nèi)對(duì)象的命名。通常若不指定名稱,就沿用原 .NET 函數(shù)的名稱當(dāng)作數(shù)據(jù)庫(kù)對(duì)象的名稱。
Attribute 設(shè)置的范例如下:
編譯無(wú)誤后,接著通過(guò) Visual Studio 2005 提供的“部署(Deploy)”功能,將你所寫好的程序部署到SQL Server 2005,
部署完你的程序?qū)ο蠛?,打開(kāi)SQL Server Management Studio,在“對(duì)象資源管理器”窗口選擇剛剛 Visual Studio 2005 所連接的數(shù)據(jù)庫(kù)AdventureWorks,你可發(fā)現(xiàn)在“程序集(Assemblies)”這個(gè)目錄底下多了一個(gè)節(jié)點(diǎn)YukonCLR。
“可編程性(Programmability)”-“存儲(chǔ)過(guò)程(Stored Procedures)”節(jié)點(diǎn)下,同時(shí)可以看到 Visual Studio 2005 遵循我們通過(guò) SqlProcedure Attribute 告知的屬性,將該 WriteHashedPassword 函數(shù)注冊(cè)成存儲(chǔ)過(guò)程。11.2.3 通過(guò)T-SQL手動(dòng)將該程序集放入到SQL Server
通過(guò) T-SQL 語(yǔ)法亦可將該程序集放入到 SQL Server 2005,這時(shí)可以使用 SQL Server Management Studio 操作畫面,通過(guò)主菜單“文件”-“新建”-“項(xiàng)目”選項(xiàng)打開(kāi)一個(gè)新的項(xiàng)目后,類型為“SQL Server 腳本”,在下方的“名稱”字段定義項(xiàng)目名稱后,通過(guò)“瀏覽”選擇項(xiàng)目存放的文件路徑。
進(jìn)入SQL Server Management Studio后,在“解決方案資源管理器”窗口內(nèi)的方案上點(diǎn)選右鍵新建項(xiàng)目,新建一個(gè)空的 T-SQL 查詢文件,如圖11-10所示:
你也可以通過(guò)主菜單“視圖”-“模板資源管理器”選項(xiàng),從“模板資源管理器”中選擇想要完成的工作,讓你不至于從完全空白的環(huán)境開(kāi)始編寫 T-SQL。圖11-11為 SQL Server Management Studio 的T-SQL 編寫環(huán)境,我們可以手動(dòng)將該組件注冊(cè)到 SQL Server 2005,部署的 T-SQL 范例程序代碼將在下一節(jié)介紹。
11.2.4 調(diào)試
在任何平臺(tái)與開(kāi)發(fā)環(huán)境中,調(diào)試都是必要的一環(huán)。而 Visual Studio 2005 與 SQL Server 2005 也提供了集成的調(diào)試環(huán)境。不管你是通過(guò) Tabular Data Stream(TDS)或是 HTTP/SOAP 協(xié)議與 SQL Server 2005 溝通,還是通過(guò) T-SQL 或 .NET 程序語(yǔ)言調(diào)用 SQL Server 2005 的對(duì)象,都可以直接進(jìn)入集成的調(diào)試環(huán)境。
在新建“SQL Server Project”項(xiàng)目時(shí),Visual Studio 2005 會(huì)自動(dòng)在項(xiàng)目之下創(chuàng)建一個(gè) TestScripts 子目錄,其內(nèi)放置 Test.sql 文件,你可以在該文件中編寫 T-SQL 語(yǔ)法,調(diào)用先前用 .NET 寫成的 SQL 對(duì)象,以此啟動(dòng)調(diào)試的機(jī)制。
Test.sql 文件內(nèi)已經(jīng)預(yù)先提供了調(diào)用各種 SQL Server 對(duì)象的語(yǔ)法范例,你可以將批注去除掉,修改成調(diào)用你先前編寫的對(duì)象。接著在需要調(diào)試的 .NET 程序代碼上設(shè)置斷點(diǎn),通過(guò)主菜單“調(diào)試”-“開(kāi)始調(diào)試”選項(xiàng)或 F5 快捷鍵就可以開(kāi)始調(diào)試。這時(shí) Visual Studio 2005 會(huì)自動(dòng)附加調(diào)試環(huán)境到 SQL Server 應(yīng)用程序(sqlserver.exe),并幫你執(zhí)行 Test.sql 內(nèi)的 T-SQL 語(yǔ)法,以打開(kāi)該 .NET 所編寫的對(duì)象,當(dāng)執(zhí)行到斷點(diǎn)所在的程序代碼時(shí),就進(jìn)入到單步調(diào)試的模式。
若上述步驟有問(wèn)題,你仍可以通過(guò) Visual Studio 2005 主菜單“調(diào)試”-“附加到進(jìn)程(Attach to Process)”選項(xiàng)打開(kāi)
通過(guò)在 SqlServer 內(nèi)執(zhí)行我們自行編寫的 .NET 對(duì)象,進(jìn)入到單步調(diào)試的環(huán)境
附加完 SqlServer.exe 程序后,再通過(guò)“SQL Server Management Studio”執(zhí)行 T-SQL 對(duì)該 .NET 對(duì)象的調(diào)用,依然可以執(zhí)行到程序代碼斷點(diǎn)的位置,進(jìn)入單步調(diào)試的模式。
集成開(kāi)發(fā)環(huán)境就介紹到此,我們接著來(lái)看通過(guò) .NET 程序語(yǔ)言如何建立 SQL Server 內(nèi)的五種數(shù)據(jù)庫(kù)對(duì)象。
11.2.1 System.Data.SqlServer 命名空間
當(dāng)用 .NET 開(kāi)發(fā) SQL Server 的內(nèi)部對(duì)象時(shí),最常使用的命名空間將會(huì)是存在 Sqlaccess.dll 程序文件內(nèi)的 System.Data.SqlServer。若你曾經(jīng)用 ADO.NET 開(kāi)發(fā)數(shù)據(jù)庫(kù)的應(yīng)用程序,則部分對(duì)象是相通的。例如 SqlConnection、SqlCommand 等,微軟的開(kāi)發(fā)小組盡量讓程序設(shè)計(jì)師在 SQL Server 內(nèi)訪問(wèn)數(shù)據(jù)與在外部訪問(wèn)數(shù)據(jù)的程序編寫方式相似,而不需要熟悉兩套開(kāi)發(fā)模式。以下稍微解釋這些對(duì)象:
SqlContext:SqlContext 類讓你可以取得 SQL Server 內(nèi)部調(diào)用者的執(zhí)行環(huán)境(Context),主要是取得 SqlPipe 類實(shí)例,用此返回結(jié)果給前端調(diào)用該數(shù)據(jù)庫(kù)對(duì)象的應(yīng)用程序,或是 SqlTriggerContext 以提供編寫觸發(fā)器(Trigger)的相關(guān)數(shù)據(jù)。SqlContext 類在讓我們所編寫的程序集與 SQL Server 進(jìn)行溝通時(shí)顯得非常重要。使用該類的程序范例如程序代碼列表11-1所示:
程序代碼列表11-1 通過(guò) SqlContext 取得用戶當(dāng)前的執(zhí)行環(huán)境
Using cnn As New SqlConnection("Context Connection=true")
Using sqlCmd As New SqlCommand
'因?yàn)?Product 數(shù)據(jù)表屬于不同的 Schema,所以需要加上 Schema 名稱
cnn.Open()
sqlCmd.Connection = cnn
sqlCmd.CommandText = "SELECT ProductNumber FROM Production.Product"
Dim sqlRead As SqlDataReader = sqlCmd.ExecuteReader()
'因?yàn)槭谴鎯?chǔ)過(guò)程,要通過(guò) SqlPipe 將運(yùn)行結(jié)果接回原來(lái) SQL Server 的輸出
Dim sqlP As SqlPipe = SqlContext.Pipe
sqlP.Send(sqlRead)
End Using
End Using
程序代碼列表11-1 僅是簡(jiǎn)單地取得 Production.Product 數(shù)據(jù)表內(nèi)的 ProductNumber 字段,然后直接返回給前端。由于被調(diào)用的對(duì)象是在用戶已經(jīng)取得的連接環(huán)境內(nèi)執(zhí)行,若要傳遞數(shù)據(jù)給用戶,就需要通過(guò)程序代碼列表 11-1 的方式引用 SqlContext 類的 Pipe 屬性,取得 SqlPipe 對(duì)象實(shí)例后,再通過(guò) Send 方法將結(jié)果返回。
SqlConnection:讓我們所編寫的程序取得對(duì)程序集實(shí)例被 SQL Server 外部的前端應(yīng)用程序調(diào)用時(shí),該應(yīng)用程序所在的數(shù)據(jù)庫(kù)連接相關(guān)設(shè)置。這些連接設(shè)置并不是由我們用 .NET 所編寫的存儲(chǔ)過(guò)程或用戶自定義函數(shù)的對(duì)象決定的,被調(diào)用的數(shù)據(jù)庫(kù)內(nèi)部對(duì)象需要與外部應(yīng)用程序使用相同的連接環(huán)境??梢杂靡韵碌某绦蛲ㄟ^(guò)連接字符串設(shè)置如下,而通過(guò)這條連接再執(zhí)行其他的 SQL 語(yǔ)法:
Using cnn As New SqlConnection("Context Connection=true")
SqlCommand:讓你傳送 T-SQL 命令到數(shù)據(jù)庫(kù)服務(wù)器,參照前述程序代碼列表 11-1 的范例,可以依照一般方式創(chuàng)建 SqlCommand 對(duì)象實(shí)例,并通過(guò) SqlConnection 實(shí)例來(lái)執(zhí)行取得產(chǎn)品編號(hào)的 T-SQL 語(yǔ)法。
SqlParameter:用以設(shè)置與訪問(wèn) SqlCommand 對(duì)象內(nèi)傳遞的參數(shù)。范例程序如程序代碼列表11-2所示:
程序代碼列表 11-2 通過(guò) SqlCommand 和 SqlParameter 對(duì)象搭配SHA1 哈希算法為密碼編碼
Public Shared Sub WriteHashedPassword(ByVal UserName As String, ByVal Password As String)
'將賬號(hào)/密碼經(jīng)過(guò) Sha1 Hash 口算法換算后,再存入數(shù)據(jù)表
Try
Using cnn As New SqlConnection("Context Connection=true")
cnn.Open()
Using sqlCmd As New SqlCommand
Dim sh1 As New SHA1Managed
Dim uEncode As New UnicodeEncoding
'將密碼以 SHA1 計(jì)算哈希值,再以 Base64 編碼。
Dim txtBytes As Byte() = uEncode.GetBytes(Password)
Dim hashedPassword As Byte() = sh1.ComputeHash(txtBytes)
Dim strHash As String = Convert.ToBase64String(hashedPassword)
Dim dml As String = "INSERT NamePass VALUES(@UserName,@HashAsString)"
With sqlCmd
.Connection = cnn
.CommandText = dml
'通過(guò) SqlParameter 對(duì)象設(shè)置 SqlCommand 對(duì)象所包含 T-SQL 語(yǔ)法
'需要的參數(shù)
.Parameters.Add(New SqlParameter("@UserName", SqlDbType.NVarChar, 50))
.Parameters(0).Value = UserName
.Parameters.Add(New SqlParameter("@HashAsString", SqlDbType.NVarChar, 100))
.Parameters(1).Value = strHash
sqlCmd.ExecuteNonQuery()
End With
End Using
cnn.Close()
End Using
Catch ex As Exception
Dim fs As New FileStream("C:\YukonCLR.log", FileMode.OpenOrCreate, FileAccess.Write)
Dim sw As New StreamWriter(fs)
sw.WriteLine(ex.ToString())
sw.Close()
End Try
End Sub
常常有朋友詢問(wèn)如何將用戶輸入的密碼通過(guò)哈希(Hash)算法計(jì)算過(guò)后再放入數(shù)據(jù)庫(kù)中,在以往筆者只能建議在應(yīng)用程序端編寫,現(xiàn)在相同的語(yǔ)法可以寫成存儲(chǔ)過(guò)程保存在 SQL Server 內(nèi),如程序代碼列表11-2 所示。而一般的用戶只需要簡(jiǎn)單地調(diào)用存儲(chǔ)過(guò)程,就可以將密碼通過(guò) .NET Framework 提供的 SHA1 哈希算法編碼后,再存入到數(shù)據(jù)表。
SqlPipe:將執(zhí)行結(jié)果或信息送回前端應(yīng)用程序,程序范例可以參照程序代碼列表 11-1 最后兩行。如果前端是通過(guò) ADO 或 ADO.NET 對(duì)象訪問(wèn) SQL Server,而我們編寫的對(duì)象返回文字信息,則會(huì)被前端視為 Connection 對(duì)象的 InfoMessage 事件,范例如下。你也可以返回單一條記錄或是整個(gè)數(shù)據(jù)集合。
Dim pipe As SqlPipe = SqlContext.Pipe
‘傳送信息
pipe.Send(“完成事務(wù)”)
SqlDataReader:通過(guò) SQL Server 提供的只能向前移動(dòng)(forward-only)、只讀(read-only)游標(biāo)(Cursor)來(lái)訪問(wèn)數(shù)據(jù)。
Dim sdr As SqlDataReader = cmd.ExecuteReader()
While sdr.Read()
Debug.WriteLine(sdr("EmployeeID") & "-" & sdr(1))
End While
sdr.Close()
上述范例程序中通過(guò) Read 函數(shù)逐條讀出數(shù)據(jù),直到數(shù)據(jù)記錄讀取完畢,Read 函數(shù)會(huì)返回 false,我們據(jù)此退出循環(huán)。
System.Transactions.Transaction:.NET Framework2.0新增了 System.Transactions 命名空間,在其內(nèi)可提供新的事務(wù)管理架構(gòu)與功能。若只就此處的 SQL Server 內(nèi)部對(duì)象而言,你不太需要管理,因?yàn)楫?dāng)通過(guò) SqlConnection 取得對(duì)象執(zhí)行環(huán)境的連接時(shí),若該連接已經(jīng)有事務(wù),則會(huì)自動(dòng)加入,你可以通過(guò) Transaction 的靜態(tài)屬性 Current 取得當(dāng)前的事務(wù)狀況,以此完成或恢復(fù)事務(wù)。范例程序如下:
Catch ex As Exception
Transaction.Current.Rollback
約略看完 ADO.NET 2.0 與創(chuàng)建 SQL Server 2005 對(duì)象相關(guān)的類后,我們接著來(lái)看一下,如何通過(guò) Visual Studio 2005 建構(gòu)對(duì)象。
11.2.2 通過(guò)Visual Studio 2005創(chuàng)建供SQL Server 2005用的Assembly
首先在 Visual Studio 2005 新建一個(gè)新的項(xiàng)目,類型為“SQL Server Project”,
由于需要 Visual Studio 2005 集成開(kāi)發(fā)環(huán)境幫我們部署已開(kāi)發(fā)好的數(shù)據(jù)庫(kù)對(duì)象到 SQL Server 2005 實(shí)例的數(shù)據(jù)庫(kù)內(nèi),所以相關(guān)的連接設(shè)置必須正確。若在圖11-3 設(shè)置錯(cuò)誤,可以在進(jìn)入項(xiàng)目后,在“解決方案資源管理器”窗口內(nèi)以鼠標(biāo)右鍵點(diǎn)選項(xiàng)目名稱,通過(guò)快捷選項(xiàng)“屬性(Properties)”,或是鼠標(biāo)雙擊項(xiàng)目下的“My Project”節(jié)點(diǎn),另外,Visual Basic.NET 默認(rèn)的根命名空間(Root Namespace)和程序集名稱(Assembly Name)將會(huì)與項(xiàng)目名稱相同,在部署程序集到 SQL Server 2005 時(shí)將會(huì)用到這兩個(gè)名稱。若你想更改根命名空間或程序集名稱可以進(jìn)入“應(yīng)用程序(Application)”頁(yè)簽修改
接著在Visual Studio 2005的項(xiàng)目?jī)?nèi)選取工具選單上的“項(xiàng)目”-“添加新項(xiàng)目”,打開(kāi)如圖11-6的對(duì)話框,在對(duì)話框內(nèi)選擇“Stored Procedure”項(xiàng)目,或于“解決方案資源管理器”內(nèi)使用快捷選項(xiàng),選擇“新建項(xiàng)目(New Item)”亦可。
在圖11-6 中填入適當(dāng)名稱后,點(diǎn)選“添加(Add)”按鈕,以添加定義“Stored Procedure”的模板。
在此,我們創(chuàng)建一個(gè)存儲(chǔ)過(guò)程,內(nèi)容如上文程序代碼列表 11-2 的定義。
在各對(duì)象前可以加上 System.Data.Sql 命名空間下所提供的一組 Attribute 來(lái)告知該函數(shù)的用途,同時(shí)可以通過(guò)該 Attribute 的 name 屬性(Property)來(lái)告知該函數(shù)或類型創(chuàng)建到 SQL Server 內(nèi)對(duì)象的命名。通常若不指定名稱,就沿用原 .NET 函數(shù)的名稱當(dāng)作數(shù)據(jù)庫(kù)對(duì)象的名稱。
Attribute 設(shè)置的范例如下:
編譯無(wú)誤后,接著通過(guò) Visual Studio 2005 提供的“部署(Deploy)”功能,將你所寫好的程序部署到SQL Server 2005,
部署完你的程序?qū)ο蠛?,打開(kāi)SQL Server Management Studio,在“對(duì)象資源管理器”窗口選擇剛剛 Visual Studio 2005 所連接的數(shù)據(jù)庫(kù)AdventureWorks,你可發(fā)現(xiàn)在“程序集(Assemblies)”這個(gè)目錄底下多了一個(gè)節(jié)點(diǎn)YukonCLR。
“可編程性(Programmability)”-“存儲(chǔ)過(guò)程(Stored Procedures)”節(jié)點(diǎn)下,同時(shí)可以看到 Visual Studio 2005 遵循我們通過(guò) SqlProcedure Attribute 告知的屬性,將該 WriteHashedPassword 函數(shù)注冊(cè)成存儲(chǔ)過(guò)程。11.2.3 通過(guò)T-SQL手動(dòng)將該程序集放入到SQL Server
通過(guò) T-SQL 語(yǔ)法亦可將該程序集放入到 SQL Server 2005,這時(shí)可以使用 SQL Server Management Studio 操作畫面,通過(guò)主菜單“文件”-“新建”-“項(xiàng)目”選項(xiàng)打開(kāi)一個(gè)新的項(xiàng)目后,類型為“SQL Server 腳本”,在下方的“名稱”字段定義項(xiàng)目名稱后,通過(guò)“瀏覽”選擇項(xiàng)目存放的文件路徑。
進(jìn)入SQL Server Management Studio后,在“解決方案資源管理器”窗口內(nèi)的方案上點(diǎn)選右鍵新建項(xiàng)目,新建一個(gè)空的 T-SQL 查詢文件,如圖11-10所示:
你也可以通過(guò)主菜單“視圖”-“模板資源管理器”選項(xiàng),從“模板資源管理器”中選擇想要完成的工作,讓你不至于從完全空白的環(huán)境開(kāi)始編寫 T-SQL。圖11-11為 SQL Server Management Studio 的T-SQL 編寫環(huán)境,我們可以手動(dòng)將該組件注冊(cè)到 SQL Server 2005,部署的 T-SQL 范例程序代碼將在下一節(jié)介紹。
11.2.4 調(diào)試
在任何平臺(tái)與開(kāi)發(fā)環(huán)境中,調(diào)試都是必要的一環(huán)。而 Visual Studio 2005 與 SQL Server 2005 也提供了集成的調(diào)試環(huán)境。不管你是通過(guò) Tabular Data Stream(TDS)或是 HTTP/SOAP 協(xié)議與 SQL Server 2005 溝通,還是通過(guò) T-SQL 或 .NET 程序語(yǔ)言調(diào)用 SQL Server 2005 的對(duì)象,都可以直接進(jìn)入集成的調(diào)試環(huán)境。
在新建“SQL Server Project”項(xiàng)目時(shí),Visual Studio 2005 會(huì)自動(dòng)在項(xiàng)目之下創(chuàng)建一個(gè) TestScripts 子目錄,其內(nèi)放置 Test.sql 文件,你可以在該文件中編寫 T-SQL 語(yǔ)法,調(diào)用先前用 .NET 寫成的 SQL 對(duì)象,以此啟動(dòng)調(diào)試的機(jī)制。
Test.sql 文件內(nèi)已經(jīng)預(yù)先提供了調(diào)用各種 SQL Server 對(duì)象的語(yǔ)法范例,你可以將批注去除掉,修改成調(diào)用你先前編寫的對(duì)象。接著在需要調(diào)試的 .NET 程序代碼上設(shè)置斷點(diǎn),通過(guò)主菜單“調(diào)試”-“開(kāi)始調(diào)試”選項(xiàng)或 F5 快捷鍵就可以開(kāi)始調(diào)試。這時(shí) Visual Studio 2005 會(huì)自動(dòng)附加調(diào)試環(huán)境到 SQL Server 應(yīng)用程序(sqlserver.exe),并幫你執(zhí)行 Test.sql 內(nèi)的 T-SQL 語(yǔ)法,以打開(kāi)該 .NET 所編寫的對(duì)象,當(dāng)執(zhí)行到斷點(diǎn)所在的程序代碼時(shí),就進(jìn)入到單步調(diào)試的模式。
若上述步驟有問(wèn)題,你仍可以通過(guò) Visual Studio 2005 主菜單“調(diào)試”-“附加到進(jìn)程(Attach to Process)”選項(xiàng)打開(kāi)
通過(guò)在 SqlServer 內(nèi)執(zhí)行我們自行編寫的 .NET 對(duì)象,進(jìn)入到單步調(diào)試的環(huán)境
附加完 SqlServer.exe 程序后,再通過(guò)“SQL Server Management Studio”執(zhí)行 T-SQL 對(duì)該 .NET 對(duì)象的調(diào)用,依然可以執(zhí)行到程序代碼斷點(diǎn)的位置,進(jìn)入單步調(diào)試的模式。
集成開(kāi)發(fā)環(huán)境就介紹到此,我們接著來(lái)看通過(guò) .NET 程序語(yǔ)言如何建立 SQL Server 內(nèi)的五種數(shù)據(jù)庫(kù)對(duì)象。

