在 Visual Basic .NET 中使用存储过程(2)

visual|存储过程

从存储过程返回值
以上示例有一个不足之处。Northwind Customers 表使用数字字母形式的主键,并且必须由插入数据的应用程序生成。也就是说,如果使用以上程序插入新记录,则必须为 CustomerID 自行创建由五个字符组成的值。

在真实软件中,为新记录自动生成主键更为常见。主键通常是按顺序分配的长整数。

为新记录设置主键有两种基本技术。应用程序可调用生成下一个可用 ID 的存储过程,然后将此 ID 直接放到 DataSet 的新行中。或者,用于插入记录的存储过程可以为记录派生新 ID,然后将其作为返回值传递回应用程序。

第一种技术需要一点额外的逻辑来获取新 ID 并将其放到新记录的相应位置。使用存储过程执行插入操作与以上示例类似。

但第二种技术要求在存储过程中使用一种新型参数。到目前为止我们见到的所有参数都是默认类型,即输入参数。实际上参数分四种类型:

Input 此参数只用于将信息从应用程序传输到存储过程。
InputOutput 此参数可将信息从应用程序传输到存储过程,并将信息从存储过程传输回应用程序。
Output 此参数只用于将信息从存储过程传输回应用程序。
ReturnValue 此参数表示存储过程的返回值。SQL Server 的存储过程参数列表中不显示该参数。它只与存储过程的 RETURN 语句中的值相关联。

存储过程为主键生成新值后,通常使用存储过程中的 RETURN 语句返回该值,因此用来访问该值的参数类型是 ReturnValue 参数。

ReturnValue 参数与其他类型的参数有一个重要的区别。通常,在 ADO.NET 中为 Command 对象配置的参数的顺序并不重要。参数名称只用来与存储过程中相应的参数相匹配。但是,对于 ReturnValue 参数,它必须是列表中的第一个参数。

也就是说,为 Command 对象配置 ReturnValue 参数时,必须首先在代码中配置该参数,这样它才能获取集合中的第一个数字索引。如果先配置任何其他参数,ReturnValue 参数将不能正常工作。

为了说明带返回值的存储过程的用法,我们编写一个在 Northwind Products 表中插入记录的示例。此表被设置为使用 Identity 列自动创建新产品 ID。遗憾的是,Northwind 示例数据库不包含执行所需操作的存储过程,所以在完成示例其余部分之前,我们需要向数据库插入一个这样的存储过程。

转到 Visual Studio .NET 中的 Server Explorer(服务器资源管理器)。打开 SQL Server 的节点,打开 SQL Server 实例的节点,然后打开 Northwind 数据库的节点。

右键单击 Stored Procedures(存储过程)节点,选择 New Stored Procedure(新建存储过程)。在出现的编辑窗口中,用以下文本替换其中的所有文本:

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

现在关闭编辑窗口,当系统询问您是否要保存更改时,单击 Yes(是)。现在存储过程就已保存到数据库中,并被命名为 MSDNInsertProduct。

现在便可以编写代码来使用此存储过程。新建 Windows 应用程序,在空白 Form1 上,放置锚定到所有四个边的 DataGrid,还需添加名为 btnFill 和 btnInsertProduct 的两个按钮。将 btnFill 的 Text 属性设置为 Fill,将 btnInsertProduct 的 Text 属性设置为 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

它与本文前面所讲的代码大致相同,所以我们不再赘述。不要忘记必要时更改连接字符串,并在项目代码的顶部为 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
' 为存储过程设置参数
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"))

此代码与如上所示的代码类似,只是为返回值配置参数的代码行不同。请注意,它是第一个参数,并被设置为将返回值放回到 ProductID 字段中。

用于向数据集中插入新行的代码是标准 ADO.NET 代码,所以我们就不再赘述。它为产品记录创建一行新的适当结构(使用产品 DataTable 的 NewRow 方法),然后将数据放入行中,最后向产品 DataTable 的 Rows 集合中添加行。

现在运行程序进行测试。单击 Fill 按钮,但不对网格中的数据进行任何更改。然后按 Insert Product 按钮。将插入 Billy's Sesame Oil 的新产品记录,并且出现的消息框会通知您为其返回的 ProductID。还可以打开网格中的 Products 表,滚动到底部,并看到已添加了新行。

使用 Server Explorer(服务器资源管理器)编写参数代码
以上代码编写起来既冗长又繁琐。但是,DataAdapter Configuration Wizard(数据适配器配置向导)提示可以使用 Visual Studio 为我们编写此代码。DataAdapter Configuration Wizard(数据适配器配置向导)为完整配置所需的四个存储过程(分别是 Select、Update、Insert 和 Delete)生成了代码。假设您象以上示例一样只需要一个存储过程的代码,可以将其截短。要获得只与一个存储过程通信的预先编写好的代码,只需展开 Server Explorer(服务器资源管理器)以显示需要访问的存储过程,然后将该存储过程拖到设计界面上。将看到为该存储过程创建的 DataAdapter 和 Command 对象,代码的设计器部分包含为该存储过程配置参数所需的所有代码。可以按原样使用该代码,也可以根据需要复制并调整后使用。

小结
本文中的示例仍是演示软件,但至少足以向您说明如何访问存储过程,以便您开始编写自己的真实软件。当然,您需要了解要访问的存储过程,并且可能需要向数据库管理员 (DBA) 或其他组员咨询以获取该信息。

对于复杂系统,存储过程有许多优势。希望您在本文中学到了足够的知识,可以不必担心如何开始使用它们。第一次尝试编写代码时,您可能希望使用 DataAdapter Wizard(DataAdapter 向导)或 Server Explorer(服务器资源管理器)。但如果您能在必要时自行编写访问代码,则可以更有效地使用存储过程。

时间: 2024-08-18 03:31:22

在 Visual Basic .NET 中使用存储过程(2)的相关文章

在 Visual Basic .NET 中使用存储过程(1)

visual|存储过程 在 Visual Basic .NET 中使用存储过程 Billy Hollis 2002年9月14日 从 MSDN Code Center 下载 StoredProcVB.NET.exe 示例文件(英文).(http://msdn.microsoft.com/code/default.asp?url=/code/sample.asp?url=/msdn-files/026/002/872/msdncompositedoc.xml) 摘要:Billy Hollis 解释了

Visual Basic .NET中的语言创新

visual Visual Basic .NET中的语言创新 引言 要快速地创建企业Web应用程序,开发人员必须依靠可伸缩的.健壮的.可重用的商务逻辑.在过去的几年中,面向对象的程序设计已经成为了创建满足这些需求的系统的主要技术.使用面向对象的程序设计语言可以使得大型系统更容易理解,更容易调试,并且更新速度更快. 为了使Visual Basic开发人员从面向对象的设计中获益,简化企业Web应用程序的开发,将在Visual Basic的下一个版本 - Visual Basic .NET中支持包括实

.net入门之VB篇:Visual Basic.Net中的文件操作(一)

visual Visual Basic.Net中有三种访问文件系统的方法:第一种是使用 Visual Basic 运行时函数进行文件访问 (VB传统方式直接文件访问):第二种是通过.Net中的System.IO模型访问:第三种是通过文件系统对象模型FSO访问. 文件是存储在某种介质上数据的集合,就其本身来讲,文件只不过是磁盘上的一系列相关的数据字节.当应用程序访问文件时,它必须假定字节是否表示字符.数据记录.整数.字符串等.通过指定文件的访问类型来告诉应用程序假定什么内容. Visual Bas

Visual Basic.NET 中的语言新变化

visual 简介 要快速创建企业级的Web应用程序,开发人员必须依赖于可伸缩性.强壮性和可重用性等商业逻辑.在过去的几年中,面向对象的程序设计成为符合这些要求的系统的首要方法.使用面向对象的编程语言有助于使大规模的系统更易于理解.更易于调试.升级更迅速. 为了使Visual Basic开发人员能够从面向对象设计中受益并简化企业级Web应用程序的开发,Visual Basic的下一个版本­--Visual Basic.NET将支持包括实现继承在内的全部面向对象的语言特性.有了这些语言特性,Vis

在 Visual Basic .NET 中实现后台进程

visual|后台|进程 Rockford LhotkaMagenic Technologies 2002年10月1日 从 MSDN Code Center 下载 VBbackground.exe 示例文件(英文).(请注意,在示例文件中,程序员的注释使用的是英文,本文中将其译为中文是为了便于读者进行理解.) 摘要:Rocky Lhotka 建议并实现了一个结构化架构示例,该架构可用于充当辅助线程和 UI 线程之间的媒介,从而简化编写多线程辅助代码和 UI 以对其进行控制的过程.该架构包括可下载

Visual Basic .NET 中动态加载类(一)

visual|动态|加载 Visual Basic .NET 中动态加载类 · ··Microsoft 摘要:理想情况下,编写软件系统之前我们就应该知道此软件系统需要完成哪些操作.但实际情况并非如此,因此我们的系统应该是可以调整的. 最能体现这种适应性的是动态集成新功能的能力.例如,在 Windows 窗体应用程序中,这种能力是指加载编译原始应用绦蚝芫靡院蟠唇ǖ拇疤宓哪芰Α?/P> 这种操作在 Microsoft Visual Basic 6.0 中几乎是不可能的,但是在 Visual Basi

Visual Basic .NET 中动态加载类 (三)

visual|动态|加载 ··Microsoft 步骤 8:用新的窗体信息更新配置文件 现在,我们已经创建了一些新窗体,还需要在配置文件中引用它们.请用以下代码行替换 FormsOnTheFly.exe.config 中的占位符信息: <add key="First Form" value="C:\NewForms\FirstForm.dll~FirstForm.Form1"></add><add key="Second Fo

EXCEL窗口在Visual Basic窗口中显示技巧

Visual http://www.aliyun.com/zixun/aggregation/11183.html">Basic是常用的应用软件开发工具之一,由于Visual Basic的报表功能有限,而且一但报表格式发生变化,就得相应修改程序,给应用软件的维护工作带来极大的不便.因此有很多程序员现在已经充分利用EXECL的强大报表功来实现报表功能.但由于Visual Basic与EXCEL由于分别属于不同的应用系统,如何把它们有机地结合在一起,是一个值得我们研究的课题. 一. Visua

Visual Basic .NET 中动态加载类 (二)

visual|动态|加载 Microsoft 步骤 3:创建配置文件以存放可用窗体 应用程序在运行时需要的某些信息可能在编译时无法提供,这些信息通常放置在配置文件中.在 Visual Basic 6.0 中,配置文件应该是 INI 文件或 Windows 注册表.而在 .NET 中,则使用基于 XML 的配置文件. 我们无法详细介绍配置文件,因为这个主题非常复杂.但是,您应该知道,Windows 窗体应用程序的配置文件与应用程序的 EXE 启动文件在同一个目录中.配置文件的名称与程序的 EXE