`
leonardleonard
  • 浏览: 811725 次
社区版块
存档分类
最新评论

使用VS.NET2003编写存储过程

阅读更多

作者:未知   请作者速与本人联系

数据表定义了如何在数据库中存储数据,但没有说明如何存取数据。我们还需要了解读写记录以便从表中再次调用选定行和列的详细信息。开发人员通常会在其代码中编写一些特殊的查询语句,用于读写数据。这不仅会导致效率低下,还会带来安全性问题。在本应用中,所有数据存取工作都将通过 SQL Server 存储过程(stored procedures,有时称作“stored procs”或“sprocs”)来处理。使用存储过程可以提高解决方案的性能并使之更安全。此外,使用存储过程可以增加数据层的抽象级别,从而保护解决方案的其他部分不受小的数据布局和格式变化带来的影响。这样可使您的解决方案更可靠,更易于维护。

为什么不使用特殊的查询语句

我们经常会看到如下所示的文章和代码示例:

<ccid_nobr>
<ccid_code>Private Function GetSomeData(ByVal ID As Integer) As SqlDataReader
        Dim strSQL As String
        strSQL = "SELECT * FROM MyTable WHERE ID=" & ID.ToString()
        cd = New SqlCommand
        With cd
            .CommandText = strSQL
            .CommandType = CommandType.Text
            .Connection = cn
            .Connection.Open()
            Return .ExecuteReader(CommandBehavior.CloseConnection)
        End With
    End Function</ccid_code>
</ccid_nobr>

上述代码不符合要求的原因有以下几个。首先,如果将 SQL 查询语句嵌套在代码中,那么只要数据层发生任何变化,都必须编辑并重新编译代码层。这样就会带来诸多不便。还可能会导致其他错误,而且通常会造成数据服务和代码之间的混乱。

其次,如果使用不经过输入验证的字符串连接 ("...WHERE ID=" & ID.ToString()),将可能使您的应用程序暴露在黑客的攻击之下。更重要的是,这样就会为恶意用户提供了在您的代码中添加其他 SQL 关键字的机会。例如,根据您的输入模式,恶意用户不仅可以输入 13 或 21 作为有效的表 ID,还可以输入 13; DELETE FROM USERS 或其他可能会带来危害的语句。完善的输入验证可以保护您的系统免受大多数 SQL 插入代码的攻击,所以最好将所有内置的 SQL 语句完全删除,使攻击者很难滥用您的应用程序数据。

最后,内置 SQL 语句的执行速度要比存储过程慢得多。创建存储过程并将其存储到数据库中时,SQL Server 会对其文本进行评估并以优化的形式进行存储,从而使之更容易在运行时为 SQL Server 所用。如果使用内置的特殊查询语句,就必须在每次运行该代码之前进行这种评估。对于那些供大量用户使用的应用程序而言,每分钟就可能需要对同一查询语句进行数百次评估。

相反,存储过程可以保持代码的简洁明了,可以提供额外的安全保护,并能提高解决方案的性能。这些都是摒弃内置查询语句而使用存储过程的原因。

将存储过程添加到 Visual Studio .NET 数据库项目中

使用 Visual Studio .NET 2003 创建存储过程非常简单。首先,您需要打开一个数据库项目。这一操作已在《使用VS.NET2003创建数据库图》中完成。然后,您可以使用代码模板创建存储过程,也可以针对 Server Explorer(服务器资源管理器)窗口中连接的数据库,使用 Visual Studio .NET 2003 直接编辑新的存储过程。本文重点介绍如何针对连接的数据库服务器直接编辑存储过程。稍后会介绍如何为以后的远程服务器安装生成所有结果脚本。

介绍使用 Visual Studio .NET 2003 编写存储过程的机制之前,还要重点强调一下与创建可靠的存储过程相关的几个一般问题。首先,最好将创建和执行存储过程的整个过程看作是多层应用程序模型的一个成熟成员。存储过程提供了一种对您的数据存取进行编程的方法。这样,您可以更好地控制整个解决方案并提高其效率。也就是说,应将存储过程集合看作是应用程序中一个独立的层。优秀的数据存取策略应允许存储过程作为独立的组件而存在。也就是说,存储过程层中需要具备安全性、错误处理以及其他构成优秀组件层的详细内容。更重要的是,应像在其他高级编程环境中那样访问 T-SQL 语言,而不是仅仅将其作为一种生成数据库查询的方式。

注意:现在,我怀疑有些读者可能在想他们并不打算对 SQL Server 进行编程,或者认为这项工作最好留给那些 DBA 们来完成。虽然具备数据库管理员经验会有所帮助,但并一定非要成为火箭科学家(这里指技艺高超的编程专家)才能很好地完成 SQL Server 编程工作。像其他语言一样,这种语言也需要花费一定的时间并通过一定的实践才能熟练掌握,在这一点上它与其他语言并没有太大的不同。如果您能够在 Microsoft Visual Basic? .NET 中编程,也就能够在 T-SQL 中编程。

使用 Visual Studio .NET 添加存储过程

下面详细介绍如何在 Visual Studio .NET 2003 中将存储过程添加到现有 SQL Server 数据库中。您需要使用服务器资源管理器打开一个新的存储过程模板,进行编辑,然后再将其保存到数据库中。下面是分步实现这一过程的示例:

·打开 Visual Studio .NET,然后打开一个现有的数据库项目(如本文前面所启动的项目)或启动一个新项目。
·在 Server Explorer(服务器资源管理器)中,展开 Data Connections(数据连接)树,找到您要使用的数据库 (DotNetKB),然后在 Stored Procedures(存储过程)节点上单击鼠标右键,打开上下文相关菜单。
·从上下文相关菜单中选择 New Stored Procedure(新建存储过程),在 Visual Studio .NET 编辑器空间中打开一个存储过程模板。现在,可以键入内容了。
·完成编辑后,只需关闭编辑器中正在编辑的页面,Visual Studio .NET 将使用存储过程的名称将该项内容保存到数据库中。如果键入的内容有误,编辑器会向您报告这些错误,您可以在保存存储过程之前修正这些错误。

下面是存储过程的一个简单示例,它返回一个主题列表。

<ccid_nobr>
<ccid_code>CREATE PROCEDURE TopicsGetList
AS
   SET NOCOUNT ON -- 不返回受影响行的值
   SELECT 
      ID,
      Title,
      Description
   FROM 
      Topics
   ORDER BY 
      Title
   RETURN @@ERROR</ccid_code>
</ccid_nobr>

在本示例中,有几点需要指出。首先,请注意 SET NOCOUNT ON 行。它告诉 SQL Server 停止为该查询计算受影响的行数,并停止向调用函数返回该值。这是一项不必要的额外工作。其次,结尾处的 RETURN @@ERROR 一行很重要。此行代码返回 SQL Server 中发生的错误的整数值。您可以在调用例程中使用此代码完成其他诊断和错误处理操作。您现在并不需要执行任何操作,但它们是创建存储过程时应该遵循的两个好习惯。

下面是一个更复杂的存储过程。此过程用于从数据库中检索单条主题记录。您会发现一些附加项,包括输入参数、返回特定值的输出参数,以及检查输入参数并在需要时返回错误的某些程序代码。

<ccid_nobr>
<ccid_code>CREATE PROCEDURE TopicsGetItem
   (
      @AdminCode char(3),
      @ID int,
      @Title varchar(30) OUTPUT,
      @Description varchar(500) OUTPUT
   )
AS
   SET NOCOUNT ON -- 不返回受影响行的值
   -- 确保是一个 Admin 用户
   IF @AdminCode<>'adm'
      BEGIN
         RETURN 100 -- 无效 admin 错误
      END
   -- 检查记录是否存在
   IF (SELECT Count(ID) FROM Topics WHERE ID=@ID)=0
      BEGIN
         RETURN 101 --- 无效 ID 代码
      END
   -- 继续执行并返回该记录
   SELECT 
      @Title=Title, 
      @Description=Description
   FROM 
      Topics
   WHERE 
      ID=@ID
   -- 返回错误,如果成功则返回 0
   RETURN @@ERROR</ccid_code>
</ccid_nobr>

在本示例中,还有几点需要指出。首先,您会在存储过程顶端看到一个参数列表。除前两个参数外,其他参数均被标记为 OUTPUT 参数。这些参数用于返回选定记录的值。使用一条记录的返回值要比返回带有所有字段的记录集合更为高效。

其次,您会发现用于检查 @AdminCode 参数值的 T-SQL 数据块,以确保传递正确的代码。如果传递的代码不正确,则传递返回代码 100 并停止执行该过程。再其次,您会发现检查 @ID 参数,以确保其代表一条现有记录。如果不是现有记录,则传送返回代码 101 并终止执行。最后,如果输入变量都有效,存储过程将尝试选择记录并返回相应的值。如果此时发生任何错误,将由该过程的最后一行代码进行处理。

注意:通常情况下,最好将自定义错误代码及其含义保存在数据库中的一个单独的表格中,或保存在解决方案可以访问的文本文件中。这样就可以轻松更新这些错误代码,并与解决方案中的其他子系统共享。因为这只是一个短小的示例,其中只使用了两个错误代码,所以我决定创建一个包含大量代码和消息的文档,以供其他子系统参考。

该解决方案中包含的存储过程超过 25 个。本文仅举一例进行说明,其他代码可以通过本文开始处的链接进行下载。最后这个示例使用一个自定义的内置标量函数。

使用自定义标量函数

有时,单独一个存储过程不足以解决问题。例如,我们的用户方案中就有一个方案要求列出某个问题的解答数目。解决此问题的方法之一是生成一个对问题的解答进行计数的子查询。另外一种方法是生成一个自定义函数,返回标量值并将其包含在问题查询中。这种方法还有一个好处,那就是我们可以在其他存储过程中再次使用该标量函数。

添加自定义函数的操作类似于添加存储过程。在 Server Explorer(服务器资源管理器)树中,在选定数据库的 Functions(函数)节点上单击鼠标右键,然后从上下文相关菜单中选择 New Scalar-Valued Function(新建标量值函数)。然后在编辑器中编辑该文档,并像保存存储过程那样保存该文档。

以下是自定义函数的代码:

<ccid_nobr>
<ccid_code>CREATE FUNCTION dbo.fn_QuestionsGetResponseCount
   (
      @ID int
   )
RETURNS int
AS
   BEGIN
      DECLARE @ResponseCount int
      Set @ResponseCount = 
      (
         SELECT 
            COUNT(Responses.ID) 
         FROM 
            Responses
         WHERE
            Responses.QuestionID=@ID
      )
      RETURN @ResponseCount
   END</ccid_code>
</ccid_nobr>

以下是使用自定义函数的存储过程:

<ccid_nobr>
<ccid_code>CREATE PROCEDURE QuestionsGetCountWithNoResponses
   (
      @Total int OUTPUT
   )
AS
   SET NOCOUNT ON -- 不返回受影响行的值
   SELECT 
      @Total=Count(ID)
   FROM 
      Questions
   WHERE 
      dbo.fn_QuestionsGetResponseCount(Questions.ID)=0
   RETURN @@ERROR</ccid_code>
</ccid_nobr>
分享到:
评论

相关推荐

    VS.net2003资源文件编辑软件源码

    在VS.NET 2003中,资源文件通常以.resx为扩展名,这些文件存储了应用程序的资源数据,并且可以被.NET Framework的编译器编译进可执行文件或库中。资源文件的编辑通常涉及到以下步骤: 1. **资源的创建与管理**:...

    VS.net九大案例代码

    【VS.NET九大案例代码】是针对Visual Studio .NET(简称VS.NET)开发环境的一系列实践教程,涵盖了在软件开发过程中可能会遇到的各种应用场景。VS.NET是一款由微软公司推出的强大的集成开发环境,支持多种编程语言,...

    基于vs.net 2003+sql server的bbs小型论坛

    这个项目是一个使用Visual Studio .NET 2003(简称VS.NET 2003)开发的简单BBS(Bulletin Board System,公告板系统)论坛,它结合了SQL Server数据库来存储和管理用户数据和论坛内容。此论坛系统旨在实现基本的在线...

    .net创建存储过程函数

    .NET 创建存储过程函数允许开发人员使用 C# 或 VB.NET 等 .NET 语言来编写 SQL Server 的存储过程、函数和触发器,而非传统的 T-SQL。SQL Server 2005 及更高版本支持与 .NET CLR(Common Language Runtime)的集成...

    摇奖机 用vs.net编写的,供大家研究使用

    【标题】:“摇奖机”是一个使用Visual Studio .NET(简称VS.NET)开发的应用程序,旨在模拟摇奖过程,提供了一种有趣且可定制化的抽奖体验。VS.NET是微软公司推出的强大开发工具,集成了代码编辑器、调试器、版本...

    ASP.NET中调用存储过程方法

    - 创建存储过程:在SQL Server或其他关系型数据库中编写并创建存储过程。 - 连接数据库:在ASP.NET中,使用ADO.NET(如SqlConnection对象)建立与数据库的连接。 - 创建命令对象:使用SqlCommand对象表示要执行的...

    ASP.NET 存储过程分页

    1. **创建存储过程**:在数据库中编写一个存储过程,该过程根据@PageSize和@PageNumber计算出开始和结束的记录索引,然后返回相应范围的记录。这通常通过SQL的`OFFSET...FETCH NEXT`语句(对于SQL Server)或`LIMIT....

    学生名册管理系统(vb.net2003)

    vb.net2003是Visual Basic .NET的早期版本,它引入了面向对象编程(OOP)的概念,支持事件驱动编程,提供了一个图形化的集成开发环境(IDE),使得程序员可以通过拖拽控件和编写代码来创建用户界面。vb.net2003支持...

    ASP.NET超强的存储过程万能真分页

    使用这个用户控件,开发者可以轻松地将存储过程集成到ASP.NET应用程序的分页功能中。只需配置好存储过程的调用,设置好每页显示的记录数,就可以实现高效的分页效果。这对于那些需要处理大量数据库记录的应用来说,...

    vs.net 2003

    在IT行业中,Visual Studio .NET 2003(简称VS.NET 2003)是一个里程碑式的开发工具,由微软公司推出,主要用于构建基于.NET Framework的应用程序。它集成了多种编程语言,如C#、VB.NET、C++ .NET等,为开发者提供了...

    使用asp.net编写的bbs论坛系统

    ASP.NET编写的BBS论坛系统是一种基于Web的应用程序,它允许用户进行在线讨论、交流观点和分享信息。这个系统的核心技术栈包括ASP.NET框架、HTML、CSS、JavaScript以及数据库技术,如SQL Server或MySQL。 ASP.NET是...

    邮政管理系统VS.net2003+SQLserver2000+Access

    在这个系统中,开发者使用了微软的.NET Framework 2003作为开发平台,这是一个早期版本的.NET框架,支持C#、VB.NET等多种编程语言。选择.NET 2003可能是因为其在当时具有稳定性和兼容性,适合构建企业级应用。 描述...

    Asp.Net Ext.Net 存储过程分页 只读取当前页数据

    接下来,我们使用Ext.Net在Asp.Net中调用这个存储过程: 1. 创建一个Ext.Net的GridPanel组件,用于展示数据。 2. 设置Store组件,配置数据源为存储过程。使用`DirectMethod`或`DirectEvents`来调用服务器端的方法。 ...

    用VS.NET和SQL+Reporting+Service开

    首先,开发者会使用VS.NET连接到SQL Server数据库,编写SQL查询或存储过程来获取数据。然后,这些数据将被SSRS报表引用,生成报表模板。VS.NET的集成开发环境使得这个过程变得直观且高效,可以在同一个环境中完成...

    VB.NET编写的五子棋游戏

    标题 "VB.NET编写的五子棋游戏" 描述了这个项目是一个使用VB.NET编程语言开发的五子棋游戏,主要用于作者的课程设计。虽然在开发过程中可能因为时间限制而显得较为匆忙,但其功能核心相对简单,易于理解,特别适合...

    asp.net存储过程 增删改查对存储过程超作

    ASP.NET存储过程是数据库操作中的常见技术,它允许开发者通过编写预编译的SQL语句集,实现数据的增、删、改、查(CRUD)操作,提高应用程序的性能和安全性。在ASP.NET中,我们可以利用ADO.NET库与数据库进行交互,...

    一个基于ASP.NET的数据库存储过程代码生成源程序

    对应的“.vb”文件(如“ListTableSchema-zh-TW.aspx.vb”)则包含了这些ASP.NET页面的后台逻辑,使用VB.NET编写,处理用户的请求,与数据库交互,并生成存储过程代码。 在这个程序中,开发者可能需要执行以下步骤...

    ASP.NET基于通用存储过程的分页

    1. **创建存储过程**:在数据库(如MySQL、SQL Server等)中编写一个存储过程,这个过程应接收两个参数,通常为当前页数(PageNumber)和每页显示的记录数(PageSize)。存储过程内部应该包含用于分页的SQL语句,如`...

    vs2003+.net移动应用开发

    总之,"vs2003+.net移动应用开发"不仅仅是关于如何编写代码,更是一种全面的开发理念,涵盖了从开发环境的选择、框架的使用、到具体功能的实现等各个方面。开发者在掌握了这些知识后,可以更加高效地为智能客户端...

    asp.net用户注册代码

    ASP.NET 是微软公司推出的一种基于 .NET Framework 的Web应用程序开发平台,它提供了丰富的工具和库,使得开发者可以方便地创建动态、交互式的网站。在ASP.NET中,用户注册功能是构建任何社交网络或在线服务的基本...

Global site tag (gtag.js) - Google Analytics