我們作者通常將軟件分為兩類 - 真實(shí)軟件和演示軟件。真實(shí)軟件是在真實(shí)環(huán)境中使用的軟件。演示軟件用于闡釋編程概念。
您在文章和書籍中看到的大部分代碼都是演示軟件。它必須比真實(shí)軟件簡單,否則讀者將為那些與闡釋的概念無關(guān)的細(xì)節(jié)而費(fèi)神。但有時(shí)演示軟件又過于極端。追求簡單會(huì)忽略開發(fā)人員編寫真實(shí)軟件所需的細(xì)節(jié)。
最近我在數(shù)據(jù)訪問方面就曾遇到這樣一個(gè)問題。實(shí)際上,我見過的每個(gè)數(shù)據(jù)訪問示例都使用 SQL 語句從關(guān)系數(shù)據(jù)庫(例如,Microsoft SQL Server?)中讀取或向其中寫入。然而,在真實(shí)環(huán)境中,除了對有限的小型系統(tǒng)適用以外,這是很不可取的編程方法。結(jié)構(gòu)合理的 n 層應(yīng)用程序使用存儲(chǔ)過程代替 SQL 語句進(jìn)行數(shù)據(jù)訪問。
存儲(chǔ)過程在概念上類似于程序中的函數(shù)。它們獲取輸入?yún)?shù),以黑盒模式運(yùn)行并返回相應(yīng)信息。與函數(shù)不同的是,存儲(chǔ)過程由數(shù)據(jù)庫引擎執(zhí)行,而不是在程序中執(zhí)行。也就是說,將信息輸入到存儲(chǔ)過程或從中輸出信息都必須通過與數(shù)據(jù)庫交互的技術(shù)來完成。在 Microsoft Visual Basic? 6.0 中,該技術(shù)就是傳統(tǒng)的 ADO。在 Visual Basic .NET 中,我們可以使用 ADO.NET 完成該任務(wù)。
對于許多編程任務(wù)而言,Visual Basic .NET 使得通過存儲(chǔ)過程訪問數(shù)據(jù)比使用 Visual Basic 6.0 容易得多。其中有一些用來幫助該過程的向?qū)В坏┠鷮W(xué)會(huì)如何避免一些錯(cuò)誤之后,即使使用 ADO.NET 從頭編寫這些邏輯也并不復(fù)雜。
本文介紹了一些在 ADO.NET 中使用存儲(chǔ)過程的基本技巧,并從只讀操作開始,一直到如何使用存儲(chǔ)過程進(jìn)行數(shù)據(jù)插入、刪除和更新。
您無需精通存儲(chǔ)過程的編寫也可從本文受益。許多大型編程小組的開發(fā)人員需要使用他人編寫的存儲(chǔ)過程。我們的示例之一需要將存儲(chǔ)過程插入到示例數(shù)據(jù)庫中,但我們將逐步介紹這個(gè)任務(wù)。
ADO.NET 簡介本文假設(shè)您已經(jīng)了解了 ADO.NET 的基礎(chǔ)知識(shí)。如果您在工作中從未使用過 ADO.NET 中的 DataAdapter 、 DataSet 和 Command 對象,則應(yīng)閱讀一些介紹 ADO.NET 的文章,包括 Rocky 為本專欄撰寫的名為 ADO.NET 與您一文。
簡而言之, DataSet 在 ADO.NET 中用作數(shù)據(jù)容器,并在與數(shù)據(jù)庫斷開連接時(shí)使用。 DataSet 包含一個(gè)或多個(gè) DataTable ,每個(gè) DataTable 都包含行集合。對于那些熟悉傳統(tǒng) ADO 環(huán)境的用戶來說, DataTable 可被看作是斷開連接的 Recordset。
DataAdapter 在連接到數(shù)據(jù)庫時(shí)工作。單個(gè) DataAdapter 的作用是使用數(shù)據(jù)庫中的數(shù)據(jù)填充某個(gè) DataTable ,或?qū)? DataTable 中的更改寫回到數(shù)據(jù)庫,或者二者兼而有之。
DataAdapter 要求 Command 對象執(zhí)行各種數(shù)據(jù)庫操作。 Command 對象存放 SQL 語句或指定數(shù)據(jù)訪問實(shí)現(xiàn)方法的存儲(chǔ)過程名稱。每個(gè) DataAdapter 有四個(gè)屬性,指定用于四種數(shù)據(jù)訪問類型之一的命令對象。
- SelectCommand :此 Command 對象用于從數(shù)據(jù)庫中選擇數(shù)據(jù)。
- UpdateCommand :此 Command 對象用于更新數(shù)據(jù)庫中的現(xiàn)有記錄。
- InsertCommand :此 Command 對象用于向數(shù)據(jù)庫中插入新記錄。
- DeleteCommand :此 Command 對象用于刪除數(shù)據(jù)庫中的現(xiàn)有記錄。
圖 1 闡釋了這些對象及其關(guān)系。
圖 1:用于訪問存儲(chǔ)過程的主要 ADO.NET 類以及它們之間的關(guān)系
到目前為止,您所看到的演示軟件示例可能將其 Command 對象配置為使用 SQL 語句進(jìn)行數(shù)據(jù)訪問。實(shí)際上,某些示例可能完全跳過了 Command 對象的創(chuàng)建,這是因?yàn)? DataAdapter 的某個(gè)構(gòu)造函數(shù)允許 Command 對象選擇后臺(tái)創(chuàng)建的數(shù)據(jù)。在使用存儲(chǔ)過程之前,讓我們運(yùn)行這樣一個(gè)示例進(jìn)行比較。
本文中的所有示例都使用 SQL Server 附帶的 Northwind 示例數(shù)據(jù)庫。我們還使用專門為 SQL Server 創(chuàng)建的 ADO.NET 類,而不是普通的 OLE DB 類。為了便于訪問這些 SQL Server 類,所有示例都需要在應(yīng)用程序的代碼頂部加上以下代碼行:
Imports System.Data.SQLClient
現(xiàn)在,讓我們看看不使用存儲(chǔ)過程執(zhí)行數(shù)據(jù)訪問的第一個(gè)示例。在此示例中,我們將在 Northwind 數(shù)據(jù)庫 Products 表中檢索所有產(chǎn)品。創(chuàng)建一個(gè)新 Windows 應(yīng)用程序,在出現(xiàn)的空白 Form1 上,放置一個(gè)按鈕和一個(gè) DataGrid。將 DataGrid 的 Anchor 屬性設(shè)置為全部四個(gè)邊,使之隨表單的擴(kuò)展而擴(kuò)展。在按鈕的 Click 事件中,放置以下代碼:
Dim sConnectionString As String = _
"server=localhost;uid=sa;pwd=;database=Northwind" Dim sSQL As String = "SELECT * FROM Products" Dim daGetProducts As New SqlDataAdapter(sSQL, sConnectionString) Dim dsProducts As New DataSet() daGetProducts.Fill(dsProducts, "Products") DataGrid1.DataSource = dsProducts.Tables("Products") |
根據(jù)計(jì)算機(jī)配置的不同,可能需要更改連接字符串。建立數(shù)據(jù)庫連接后,其余代碼應(yīng)該可以正常運(yùn)行。此演示軟件說明了填入和使用 DataSet 的最簡單方法。
請注意,代碼并不創(chuàng)建 Connection 對象或 Command 對象。事實(shí)上,沒有這些對象,ADO.NET 便無法工作,但它們是在后臺(tái)創(chuàng)建并使用的。實(shí)例化 SqlDataAdapter 的代碼行傳入 SQL 字符串(用于配置后臺(tái) Command 對象)和連接字符串(用于配置后臺(tái) Connection 對象)。
我們可以將此代碼更改為使用顯式 Connection 和 Command 對象,以便稍稍遠(yuǎn)離演示軟件。在表單上再放置一個(gè)按鈕,并將以下代碼放到 Click 事件中:
Dim sConnectionString As String = _
Dim cnNorthwind As New SqlConnection(sConnectionString)
Dim daGetProducts As New SqlDataAdapter(cmdProducts)
|
此代碼通過顯式創(chuàng)建 Connection 和 Command 對象,并將這些對象附加到 DataAdapter,說明了 DataAdapters 的常用性。通過在實(shí)例化 DataAdapter 時(shí)傳入 cmdProducts,DataAdapter 的 SelectCommand 將自動(dòng)設(shè)置。然后,可以立即使用 DataAdapter 訪問數(shù)據(jù)庫。
此代碼的結(jié)果與前一示例中的結(jié)果相同。盡管它有點(diǎn)接近真實(shí)軟件,但由于數(shù)據(jù)訪問是通過 SQL 語句實(shí)現(xiàn)的,因此仍然屬于演示軟件。
使用簡單存儲(chǔ)過程獲取數(shù)據(jù)
如何將此演示軟件更改為使用存儲(chǔ)過程?只需更改幾行代碼。在表單上再放置一個(gè)按鈕,并將以下代碼放到 Click 事件中:
Dim sConnectionString As String = _
Dim daGetProducts As New SqlDataAdapter(cmdProducts)
|
實(shí)例化 Command 對象時(shí),此代碼不使用 SQL 語句并替換為要使用的存儲(chǔ)過程名稱。此外,Command 對象的 CommandType 屬性必須設(shè)置為 StoredProcedure。
此后的代碼與上一個(gè)示例非常相似,但它返回不同的數(shù)據(jù)。存儲(chǔ)過程查找十件最貴的產(chǎn)品,并只返回每個(gè)產(chǎn)品的名稱和價(jià)格。
帶輸入?yún)?shù)的存儲(chǔ)過程
此示例很簡單,因?yàn)榇鎯?chǔ)過程不需要任何輸入?yún)?shù)。也就是說,查找十件最貴的產(chǎn)品不需要任何外部信息。無需外界幫助,存儲(chǔ)過程即可完成此操作。然而,多數(shù)存儲(chǔ)過程都需要輸入?yún)?shù)來執(zhí)行其功能。在下一個(gè)示例中,讓我們看看如何向存儲(chǔ)過程傳遞輸入?yún)?shù)。我們將使用 CustomerID 來獲取相關(guān)客戶的所有訂單,并使用名為 CustOrderHist 的存儲(chǔ)過程(已存在于 Northwind 數(shù)據(jù)庫中)。
在已使用的表單上再創(chuàng)建一個(gè)按鈕,并將以下代碼行放到按鈕的 Click 事件后面:
Dim sConnectionString As String = _
cmdOrders.Parameters.Add(prmCustomerID)
Dim daGetOrders As New SqlDataAdapter(cmdOrders)
|
此代碼與上一個(gè)示例中的代碼非常相似,不同之處在于創(chuàng)建 Command 對象之后,為其配置了 Parameter 對象并將此對象添加到 Command 的參數(shù)集合中。在此示例中(更接近于演示軟件)將對客戶 ID 進(jìn)行硬編碼,參數(shù)的 Value 屬性通常會(huì)設(shè)置為某些用戶輸入數(shù)據(jù)。但是,參數(shù)的其他屬性可以完全象此示例中那樣設(shè)置。
此示例中的所有參數(shù)設(shè)置都是顯式設(shè)置。某些開發(fā)人員喜歡這種樣式,因?yàn)樗阌谡f明。但某些開發(fā)人員喜歡使用代碼行較少的等價(jià)方法:
Dim sConnectionString As String = _
cmdOrders.Parameters.Add(New _
Dim daGetOrders As New SqlDataAdapter(cmdOrders)
|
此代碼與上一示例的作用完全相同。但每個(gè)參數(shù)只需要兩行代碼,而不是六行。如果存儲(chǔ)過程包含大量參數(shù)(如后面某些示例所示),所需代碼行的多少就會(huì)有明顯區(qū)別,因此在后面部分,我們將使用此表單。
在Visual Basic .NET中使用存儲(chǔ)過程(2)
使用存儲(chǔ)過程更新數(shù)據(jù)庫
以上示例使用存儲(chǔ)過程從數(shù)據(jù)庫中提取信息。在復(fù)雜應(yīng)用程序中使用存儲(chǔ)過程更新、插入和刪除記錄也很常見。讓我們看看如何使用 ADO.NET 完成該操作。
在第一個(gè)示例中,我們將使用 Visual Studio? .NET 中的向?qū)Ь帉懸粋€(gè)存儲(chǔ)過程集合,并創(chuàng)建使用這些過程的代碼。盡管我們只需在此示例中編寫最少量的代碼,但檢查向?qū)?chuàng)建的代碼有助于我們理解除獲取數(shù)據(jù)以外,有關(guān)與存儲(chǔ)過程交互操作的過程。
在此示例中,我們將使用 Northwind 示例數(shù)據(jù)庫中的 Customers 表。安裝后的 Northwind 數(shù)據(jù)庫中不包含用于更新、插入或刪除客戶的存儲(chǔ)過程,但 Visual Studio .NET 中的 DataAdapter Configuration Wizard(數(shù)據(jù)適配器配置向?qū)В┛奢p松地為我們編寫一些存儲(chǔ)過程。
啟動(dòng)新的 Windows Application (Windows 應(yīng)用程序)項(xiàng)目。在空白的 Form1 上,放置一個(gè) DataGrid 和兩個(gè)按鈕。和先前一樣,更改 DataGrid 的 Anchor 屬性使之錨定到全部四個(gè)邊。將按鈕命名為 btnFill 和 btnUpdate ,并分別將其 Text 屬性更改為 Fill 和 Update 。
轉(zhuǎn)到 Toolbox (工具箱)的 Data (數(shù)據(jù))選項(xiàng)卡,將 SqlDataAdapter 控件拖動(dòng)到窗體上,然后釋放鼠標(biāo)。這將啟動(dòng) DataAdapter Configuration Wizard(數(shù)據(jù)適配器配置向?qū)В螕? Next (下一步)按鈕開始向向?qū)е休斎胄畔ⅰ?
首先,需要選擇一個(gè)到 Northwind 數(shù)據(jù)庫的連接;如果列表中未顯示所需連接,則單擊 New Connection (新建連接)按鈕創(chuàng)建一個(gè)連接。然后單擊 Next (下一步)按鈕。
下一屏幕上將出現(xiàn)三種數(shù)據(jù)訪問方法。其外觀與圖 2 類似。
圖 2:選擇用于 DataAdapter 的數(shù)據(jù)訪問類型
此時(shí),多數(shù)演示軟件示例選擇第一個(gè)選項(xiàng)來使用 SQL 語句。但是,我們將使用第二個(gè)選項(xiàng),并讓向?qū)槲覀兩梢恍┐鎯?chǔ)過程。選擇 Create new stored procedures (創(chuàng)建新存儲(chǔ)過程)選項(xiàng),然后單擊 Next (下一步)按鈕。
下一屏幕將請求 SQL 語句,指示最初從數(shù)據(jù)庫中提取的數(shù)據(jù)。但并不直接使用此 SQL 語句。SQL 語句中的信息將用于構(gòu)造存儲(chǔ)過程,以便執(zhí)行實(shí)際數(shù)據(jù)訪問。為使示例簡單起見,請輸入 SQL 語句
SELECT * FROM Customers
,然后按
Next
(下一步)按鈕。
此時(shí),向?qū)?huì)請求要?jiǎng)?chuàng)建的存儲(chǔ)過程的名稱。操作共有四種 - Select、Update、Insert 和 Delete 操作。按以下方法對其命名:
- Select: MSDNSelectCustomers
- Update: MSDNUpdateCustomer
- Insert: MSDNInsertCustomer
- Delete: MSDNDeleteCustomer
選擇 Yes, create them in the database for me (是的,在數(shù)據(jù)庫中創(chuàng)建它們。)選項(xiàng)。此時(shí),向?qū)聊粦?yīng)該如圖 3 所示。
圖 3:命名要由 DataAdapter 向?qū)?chuàng)建的存儲(chǔ)過程
單擊 Next (下一步)按鈕。向?qū)?chuàng)建存儲(chǔ)過程并在狀態(tài)欄屏幕上指示其進(jìn)度。完成后,可單擊 Finish (完成)按鈕退出向?qū)А?
向?qū)?chuàng)建了配置完整的 DataAdapter ,但未創(chuàng)建 DataSet 來存放數(shù)據(jù)。這是我們下一步要做的。在 Toolbox (工具框)的 Data (數(shù)據(jù))選項(xiàng)卡中,拖動(dòng) DataSet 控件。出現(xiàn)配置屏幕時(shí),選擇 Untyped dataset (無類型的數(shù)據(jù)集)。
現(xiàn)在我們準(zhǔn)備使用 DataAdapter 填充數(shù)據(jù)集。在 btnFill 的 Click 事件中,放入以下兩行代碼:
SqlDataAdapter1.Fill(DataSet1, "Customers")
DataGrid1.DataSource = DataSet1.Tables("Customers") |
在 btnUpdate 的 Click 事件中,放入以下代碼行:
SqlDataAdapter1.Update(DataSet1, "Customers")
現(xiàn)在我們有了一段使用存儲(chǔ)過程進(jìn)行數(shù)據(jù)訪問的有效演示軟件。可以運(yùn)行程序并單擊 Fill 按鈕獲取網(wǎng)格中的客戶列表。然后,可在窗格中編輯客戶記錄并選擇 Update 按鈕將更改放回到數(shù)據(jù)庫中。
注意: 編輯第一列(即 CustomerID )時(shí)將出現(xiàn)異常,因?yàn)樵?SQL Server 中不能更新數(shù)據(jù)庫記錄中的主鍵。
查看由向?qū)傻拇a會(huì)有所幫助,所有這些代碼最初都隱藏在 Windows Form Designer generated code(Windows 窗體設(shè)計(jì)器生成的代碼)區(qū)域中。單擊該區(qū)域的加號可展開代碼。注意以下代碼,它對所需的 SQLDataAdapter 和四個(gè)命令對象進(jìn)行了實(shí)例化:
Me.SqlDataAdapter1 = New System.Data.SqlClient.SqlDataAdapter()
Me.SqlSelectCommand1 = New System.Data.SqlClient.SqlCommand() Me.SqlInsertCommand1 = New System.Data.SqlClient.SqlCommand() Me.SqlUpdateCommand1 = New System.Data.SqlClient.SqlCommand() Me.SqlDeleteCommand1 = New System.Data.SqlClient.SqlCommand() |
此后的代碼配置每個(gè)命令對象并為其創(chuàng)建參數(shù)集合。此代碼與上一個(gè)示例相似,它們都使用帶參數(shù)的存儲(chǔ)過程。但向?qū)傻拇a使用參數(shù)的某些附加屬性,以使其與更改數(shù)據(jù)的存儲(chǔ)過程協(xié)同工作。例如,用于創(chuàng)建 SQLInsertCommand1 的 CompanyName 參數(shù)的代碼:
Me.SqlInsertCommand1.Parameters.Add(New _
System.Data.SqlClient.SqlParameter("@CompanyName", _ System.Data.SqlDbType.NVarChar, 40, "CompanyName")) |
在上一個(gè)示例中,我們只為參數(shù)名稱、數(shù)據(jù)類型和長度等設(shè)置了屬性
此代碼還會(huì)將參數(shù)的 SourceColumn 屬性設(shè)置為值 CompanyName 。該屬性指示 DataSet 的 Customers DataTable 中與此參數(shù)對應(yīng)的字段。這使 DataTable 中的值在插入操作期間自動(dòng)插入到參數(shù)的 Value 屬性中。讓我們來詳細(xì)介紹一下。
調(diào)用 SQLDataAdapter 的 Update 方法時(shí),該方法將更新 DataSet 中的單個(gè) DataTable 。當(dāng)逐行檢查 DataTable 時(shí),會(huì)查找需要更新、插入或刪除的行。當(dāng)找到需要插入到數(shù)據(jù)庫中的行后, SQLDataAdapter 將使用由其 InsertCommand 屬性設(shè)置的 Command 對象。這種情況下, Command 對象將訪問 MSDNInsertCustomer 存儲(chǔ)過程。
在該存儲(chǔ)過程運(yùn)行前,每個(gè)參數(shù)的 Value 屬性都必須從插入的行中導(dǎo)入。配置 SQLDataAdapter1 的代碼將存儲(chǔ)過程的每個(gè)參數(shù)與 DataTable 中的相應(yīng)字段相關(guān)聯(lián)。這樣,新 DataTable 行中的數(shù)據(jù)將自動(dòng)傳輸?shù)酱鎯?chǔ)過程的參數(shù)。
其他存儲(chǔ)過程參數(shù)的配置方法與此相似。但有一個(gè)不同之處值得注意。其他存儲(chǔ)過程傳入 DataTable 中數(shù)據(jù)的原始值,這些值用于檢查數(shù)據(jù)是否在您不知情的情況下發(fā)生了更改。也就是說,如果您提取了某些數(shù)據(jù),而其他人在您嘗試更新前更改了該數(shù)據(jù),您將收到并發(fā)異常。啟動(dòng)以上程序、提取客戶,然后使用工具(例如 SQL Enterprise Manager)更改記錄中的內(nèi)容,便可以看到這種情況的發(fā)生。如果您在示例程序中更改同一記錄并嘗試進(jìn)行更新,則會(huì)收到并發(fā)異常。
在Visual Basic .NET中使用存儲(chǔ)過程(3)
從存儲(chǔ)過程返回值
以上示例有一個(gè)不足之處。Northwind Customers 表使用數(shù)字字母形式的主鍵,并且必須由插入數(shù)據(jù)的應(yīng)用程序生成。也就是說,如果使用以上程序插入新記錄,則必須為 CustomerID 自行創(chuàng)建由五個(gè)字符組成的值。
在真實(shí)軟件中,為新記錄自動(dòng)生成主鍵更為常見。主鍵通常是按順序分配的長整數(shù)。
為新記錄設(shè)置主鍵有兩種基本技術(shù)。應(yīng)用程序可調(diào)用生成下一個(gè)可用 ID 的存儲(chǔ)過程,然后將此 ID 直接放到 DataSet 的新行中。或者,用于插入記錄的存儲(chǔ)過程可以為記錄派生新 ID,然后將其作為返回值傳遞回應(yīng)用程序。
第一種技術(shù)需要一點(diǎn)額外的邏輯來獲取新 ID 并將其放到新記錄的相應(yīng)位置。使用存儲(chǔ)過程執(zhí)行插入操作與以上示例類似。
但第二種技術(shù)要求在存儲(chǔ)過程中使用一種新型參數(shù)。到目前為止我們見到的所有參數(shù)都是默認(rèn)類型,即輸入?yún)?shù)。實(shí)際上參數(shù)分四種類型:
Input InputOutput Output ReturnValue
此參數(shù)只用于將信息從應(yīng)用程序傳輸?shù)酱鎯?chǔ)過程。 |
此參數(shù)可將信息從應(yīng)用程序傳輸?shù)酱鎯?chǔ)過程,并將信息從存儲(chǔ)過程傳輸回應(yīng)用程序。 |
此參數(shù)只用于將信息從存儲(chǔ)過程傳輸回應(yīng)用程序。 |
此參數(shù)表示存儲(chǔ)過程的返回值。SQL Server 的存儲(chǔ)過程參數(shù)列表中不顯示該參數(shù)。它只與存儲(chǔ)過程的 RETURN 語句中的值相關(guān)聯(lián)。 |
存儲(chǔ)過程為主鍵生成新值后,通常使用存儲(chǔ)過程中的 RETURN 語句返回該值,因此用來訪問該值的參數(shù)類型是 ReturnValue 參數(shù)。
ReturnValue 參數(shù)與其他類型的參數(shù)有一個(gè)重要的區(qū)別。通常,在 ADO.NET 中為 Command 對象配置的參數(shù)的順序并不重要。參數(shù)名稱只用來與存儲(chǔ)過程中相應(yīng)的參數(shù)相匹配。但是,對于 ReturnValue 參數(shù),它必須是列表中的第一個(gè)參數(shù)。
也就是說,為 Command 對象配置 ReturnValue 參數(shù)時(shí),必須首先在代碼中配置該參數(shù),這樣它才能獲取集合中的第一個(gè)數(shù)字索引。如果先配置任何其他參數(shù), ReturnValue 參數(shù)將不能正常工作。
為了說明帶返回值的存儲(chǔ)過程的用法,我們編寫一個(gè)在 Northwind Products 表中插入記錄的示例。此表被設(shè)置為使用 Identity 列自動(dòng)創(chuàng)建新產(chǎn)品 ID。遺憾的是,Northwind 示例數(shù)據(jù)庫不包含執(zhí)行所需操作的存儲(chǔ)過程,所以在完成示例其余部分之前,我們需要向數(shù)據(jù)庫插入一個(gè)這樣的存儲(chǔ)過程。
轉(zhuǎn)到 Visual Studio .NET 中的 Server Explorer (服務(wù)器資源管理器)。打開 SQL Server 的節(jié)點(diǎn),打開 SQL Server 實(shí)例的節(jié)點(diǎn),然后打開 Northwind 數(shù)據(jù)庫的節(jié)點(diǎn)。
右鍵單擊 Stored Procedures(存儲(chǔ)過程)節(jié)點(diǎn),選擇 New Stored Procedure(新建存儲(chǔ)過程)。在出現(xiàn)的編輯窗口中,用以下文本替換其中的所有文本:
ALTER PROCEDURE dbo.MSDNInsertProduct
SET NOCOUNT OFF;
RETURN @ProductID |
現(xiàn)在關(guān)閉編輯窗口,當(dāng)系統(tǒng)詢問您是否要保存更改時(shí),單擊 Yes(是)。現(xiàn)在存儲(chǔ)過程就已保存到數(shù)據(jù)庫中,并被命名為 MSDNInsertProduct。
現(xiàn)在便可以編寫代碼來使用此存儲(chǔ)過程。新建 Windows 應(yīng)用程序,在空白 Form1 上,放置錨定到所有四個(gè)邊的 DataGrid,還需添加名為 btnFill 和 btnInsertProduct 的兩個(gè)按鈕。將 btnFill 的 Text 屬性設(shè)置為 Fill,將 btnInsertProduct 的 Text 屬性設(shè)置為 Insert Product。
在 btnFill 的 Click 事件中,放置以下代碼:
Dim sConnectionString As String = _
"server=localhost;uid=sa;pwd=;database=Northwind" Dim sSQL As String = "SELECT * FROM Products" Dim daGetProducts As New SqlDataAdapter(sSQL, sConnectionString) Dim dsProducts As New DataSet() daGetProducts.Fill(dsProducts, "Products") DataGrid1.DataSource = dsProducts |
它與本文前面所講的代碼大致相同,所以我們不再贅述。不要忘記必要時(shí)更改連接字符串,并在項(xiàng)目代碼的頂部為 SQLClient 命名空間放置 Imports 語句。然后在 btnInsertProduct 的 Click 事件中放置以下代碼:
Dim sConnectionString As String = _
cmdInsertProduct.Parameters.Add(New SqlParameter("@ProductName", _
Dim daInsertProduct As New SqlDataAdapter()
Dim drNewProduct As DataRow
daInsertProduct.Update(dsProducts.Tables("Products")) MsgBox(drNewProduct.Item("ProductID")) |
此代碼與如上所示的代碼類似,只是為返回值配置參數(shù)的代碼行不同。請注意,它是第一個(gè)參數(shù),并被設(shè)置為將返回值放回到 ProductID 字段中。
用于向數(shù)據(jù)集中插入新行的代碼是標(biāo)準(zhǔn) ADO.NET 代碼,所以我們就不再贅述。它為產(chǎn)品記錄創(chuàng)建一行新的適當(dāng)結(jié)構(gòu)(使用產(chǎn)品 DataTable 的 NewRow 方法),然后將數(shù)據(jù)放入行中,最后向產(chǎn)品 DataTable 的 Rows 集合中添加行。
現(xiàn)在運(yùn)行程序進(jìn)行測試。單擊 Fill 按鈕,但不對網(wǎng)格中的數(shù)據(jù)進(jìn)行任何更改。然后按 Insert Product 按鈕。將插入 Billy's Sesame Oil 的新產(chǎn)品記錄,并且出現(xiàn)的消息框會(huì)通知您為其返回的 ProductID。還可以打開網(wǎng)格中的 Products 表,滾動(dòng)到底部,并看到已添加了新行。
使用 Server Explorer(服務(wù)器資源管理器)編寫參數(shù)代碼
以上代碼編寫起來既冗長又繁瑣。但是,DataAdapter Configuration Wizard(數(shù)據(jù)適配器配置向?qū)В┨崾究梢允褂?Visual Studio 為我們編寫此代碼。DataAdapter Configuration Wizard(數(shù)據(jù)適配器配置向?qū)В橥暾渲盟璧乃膫€(gè)存儲(chǔ)過程(分別是 Select、Update、Insert 和 Delete)生成了代碼。假設(shè)您象以上示例一樣只需要一個(gè)存儲(chǔ)過程的代碼,可以將其截短。要獲得只與一個(gè)存儲(chǔ)過程通信的預(yù)先編寫好的代碼,只需展開 Server Explorer(服務(wù)器資源管理器)以顯示需要訪問的存儲(chǔ)過程,然后將該存儲(chǔ)過程拖到設(shè)計(jì)界面上。將看到為該存儲(chǔ)過程創(chuàng)建的 DataAdapter 和 Command 對象,代碼的設(shè)計(jì)器部分包含為該存儲(chǔ)過程配置參數(shù)所需的所有代碼。可以按原樣使用該代碼,也可以根據(jù)需要復(fù)制并調(diào)整后使用。
小結(jié)
本文中的示例仍是演示軟件,但至少足以向您說明如何訪問存儲(chǔ)過程,以便您開始編寫自己的真實(shí)軟件。當(dāng)然,您需要了解要訪問的存儲(chǔ)過程,并且可能需要向數(shù)據(jù)庫管理員 (DBA) 或其他組員咨詢以獲取該信息。
對于復(fù)雜系統(tǒng),存儲(chǔ)過程有許多優(yōu)勢。希望您在本文中學(xué)到了足夠的知識(shí),可以不必?fù)?dān)心如何開始使用它們。第一次嘗試編寫代碼時(shí),您可能希望使用 DataAdapter Wizard(DataAdapter 向?qū)В┗?Server Explorer(服務(wù)器資源管理器)。但如果您能在必要時(shí)自行編寫訪問代碼,則可以更有效地使用存儲(chǔ)過程。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
