欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

在Visual Basic .NET中使用存儲(chǔ)過程

系統(tǒng) 2247 0

摘要: Billy Hollis 解釋了在復(fù)雜系統(tǒng)中使用存儲(chǔ)過程的好處,使存儲(chǔ)過程超出了演示軟件的范疇,并提供了有關(guān)如何訪問存儲(chǔ)過程并在您自己的應(yīng)用程序中開始使用這些存儲(chǔ)過程的實(shí)用示例。

  我們作者通常將軟件分為兩類 - 真實(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)系。

在Visual Basic .NET中使用存儲(chǔ)過程

圖 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 = _
"server=localhost;uid=sa;pwd=;database=Northwind"
Dim sSQL As String = "SELECT * FROM Products"

Dim cnNorthwind As New SqlConnection(sConnectionString)
Dim cmdProducts As New SqlCommand(sSQL, cnNorthwind)

Dim daGetProducts As New SqlDataAdapter(cmdProducts)
Dim dsProducts As New DataSet()
daGetProducts.Fill(dsProducts, "Products")
DataGrid1.DataSource = dsProducts.Tables("Products")

  此代碼通過顯式創(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 = _
"server=localhost;uid=sa;pwd=;database=Northwind"
Dim cnNorthwind As New SqlConnection(sConnectionString)
Dim cmdProducts As New _
SqlCommand("十件最貴的產(chǎn)品", cnNorthwind)
cmdProducts.CommandType = CommandType.StoredProcedure

Dim daGetProducts As New SqlDataAdapter(cmdProducts)
Dim dsProducts As New DataSet()
daGetProducts.Fill(dsProducts, "Products")
DataGrid1.DataSource = dsProducts.Tables("Products")

  實(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 = _
"server=localhost;uid=sa;pwd=;database=Northwind"
Dim cnNorthwind As New SqlConnection(sConnectionString)
Dim cmdOrders As New SqlCommand("CustOrderHist", cnNorthwind)
cmdOrders.CommandType = CommandType.StoredProcedure
' 為存儲(chǔ)過程設(shè)置參數(shù)
Dim prmCustomerID As New SqlParameter()
prmCustomerID.ParameterName = "@CustomerID"
prmCustomerID.SqlDbType = SqlDbType.VarChar
prmCustomerID.Size = 5
prmCustomerID.Value = "ALFKI"

cmdOrders.Parameters.Add(prmCustomerID)

Dim daGetOrders As New SqlDataAdapter(cmdOrders)
Dim dsOrders As New DataSet()
daGetOrders.Fill(dsOrders, "Orders")
DataGrid1.DataSource = dsOrders.Tables("Orders")

  此代碼與上一個(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 = _
"server=localhost;uid=sa;pwd=;database=Northwind"
Dim cnNorthwind As New SqlConnection(sConnectionString)
Dim cmdOrders As New SqlCommand("CustOrderHist", cnNorthwind)
cmdOrders.CommandType = CommandType.StoredProcedure

cmdOrders.Parameters.Add(New _
SqlParameter("@CustomerID", SqlDbType.VarChar, 5))
cmdOrders.Parameters("@CustomerID").Value = "ALFKI"

Dim daGetOrders As New SqlDataAdapter(cmdOrders)
Dim dsOrders As New DataSet()
daGetOrders.Fill(dsOrders, "Orders")
DataGrid1.DataSource = dsOrders.Tables("Orders")

  此代碼與上一示例的作用完全相同。但每個(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 類似。

在Visual Basic .NET中使用存儲(chǔ)過程

圖 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 所示。

在Visual Basic .NET中使用存儲(chǔ)過程

圖 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
(
@ProductName nvarchar(40),
@SupplierID int,
@CategoryID int,
@QuantityPerUnit nvarchar(20),
@UnitPrice money,
@UnitsInStock smallint,
@UnitsOnOrder smallint,
@ReorderLevel smallint,
@Discontinued bit
)
AS
declare @ProductID int

SET NOCOUNT OFF;
INSERT INTO Products(ProductName, SupplierID, CategoryID, QuantityPerUnit,
UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued) VALUES
(@ProductName, @SupplierID, @CategoryID, @QuantityPerUnit, @UnitPrice,
@UnitsInStock, @UnitsOnOrder, @ReorderLevel, @Discontinued);
SELECT @ProductID = @@IDENTITY

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 = _
"server=localhost;uid=sa;pwd=;database=Northwind"
Dim cnNorthwind As New SqlConnection(sConnectionString)
Dim cmdInsertProduct As New SqlCommand("MSDNInsertProduct", cnNorthwind)
cmdInsertProduct.CommandType = CommandType.StoredProcedure
' 為存儲(chǔ)過程設(shè)置參數(shù)
cmdInsertProduct.Parameters.Add(New SqlParameter("@RETURN_VALUE", SqlDbType.Int, 4, "ProductID"))
cmdInsertProduct.Parameters("@RETURN_VALUE").Direction = ParameterDirection.ReturnValue

cmdInsertProduct.Parameters.Add(New SqlParameter("@ProductName", _
SqlDbType.NVarChar, 40, "ProductName"))
cmdInsertProduct.Parameters.Add(New SqlParameter("@SupplierID", _
SqlDbType.Int, 4, "SupplierID"))
cmdInsertProduct.Parameters.Add(New SqlParameter("@CategoryID", _
SqlDbType.Int, 4, "CategoryID"))
cmdInsertProduct.Parameters.Add(New SqlParameter("@QuantityPerUnit", _
SqlDbType.NVarChar, 20, "QuantityPerUnit"))
cmdInsertProduct.Parameters.Add(New SqlParameter("@UnitPrice", _
SqlDbType.Money, 8, "UnitPrice"))
cmdInsertProduct.Parameters.Add(New SqlParameter("@UnitsInStock", _
SqlDbType.SmallInt, 2, "UnitsInStock"))
cmdInsertProduct.Parameters.Add(New SqlParameter("@UnitsOnOrder", _
SqlDbType.SmallInt, 2, "UnitsOnOrder"))
cmdInsertProduct.Parameters.Add(New SqlParameter("@ReorderLevel", _
SqlDbType.SmallInt, 2, "ReorderLevel"))
cmdInsertProduct.Parameters.Add(New SqlParameter("@Discontinued", _
SqlDbType.Bit, 1, "Discontinued"))

Dim daInsertProduct As New SqlDataAdapter()
daInsertProduct.InsertCommand = cmdInsertProduct
Dim dsProducts As DataSet = CType(DataGrid1.DataSource, DataSet)

Dim drNewProduct As DataRow
drNewProduct = dsProducts.Tables("Products").NewRow
drNewProduct.Item("ProductName") = "Billy's Sesame Oil"
drNewProduct.Item("SupplierID") = 4
drNewProduct.Item("CategoryID") = 7
drNewProduct.Item("QuantityPerUnit") = "6 10oz bottles"
drNewProduct.Item("UnitPrice") = 69
drNewProduct.Item("UnitsInStock") = 12
drNewProduct.Item("UnitsOnOrder") = 0
drNewProduct.Item("ReorderLevel") = 6
drNewProduct.Item("Discontinued") = False
dsProducts.Tables("Products").Rows.Add(drNewProduct)

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ǔ)過程。

在Visual Basic .NET中使用存儲(chǔ)過程


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 天堂在线免费视频 | 亚洲 无码 自拍 欧美 小说 | 国产成人精品在线 | 欧美在线视频一区二区三区 | 99国产欧美久久精品 | 亚洲性生活免费视频 | 日干夜干天天干 | 久久久婷婷一区二区三区不卡 | 久久久久免费视频 | 国产午夜三级一区二区三桃花影视 | 欧美成人精品二区三区99精品 | 欧美成人免费在线视频 | 日本精品久久久久中文字幕 | 久久制服丝袜 | 亚洲成人免费视频在线观看 | 日韩一级大片 | 成人免费看av | 午夜成人免费视频 | 国产99久久精品一区二区永久免费 | 欧美国产一区二区三区 | 涩涩撸 | 久久综合久久综合久久综合 | 久久色伦理资源站 | 久久九九精品一区二区 | 亚洲视频一区在线观看 | 亚洲综合激情另类小说区 | 波多野结衣三区 | 黑人群姣中国妞在线观看 | 日本午夜在线 | 成人看的一级毛片 | 高清中文字幕 | 成人综合久久综合 | 久久99精品国产麻豆婷婷 | 色综合久久婷婷天天 | 天天操天天操天天操 | 亚洲欧洲日产国码在线观看 | 午夜亚洲福利 | 黄色av电影在线播放 | 久久久国产99久久国产一 | 精品一二区 | 夜夜未满 18勿进的爽影院 |