首页 / 软件开发 / VC.NET / 为.net开发者提供的一份关于存储过程的评论
为.net开发者提供的一份关于存储过程的评论2009-11-07宋文锋本文适用于:Microsoft® SQL Server™Microsoft Visual Studio® .NET 2003Transact-SQL (T-SQL) Language摘要向那些在工作中主要使用.net编程语言的开发者简要介绍微软SQL Server数据库中的存储过程。揭示使用存储过程的利弊,并简要介绍在Visual Studio.net 2003中提供的一些工具和一些较好的练习,它们可以帮助你轻松的开始。序言本文的主要目的是根据应用程序的需要,介绍一些将T-SQL语句封装入存储过程时的关键性要素,以便当你在自己的系统中应用他们时可以做出明智的决定。我将介绍一些工具和较好的练习给那些希望在.net应用程序中利用它们的开发人员。我很清楚,我现在介入了一场类似不同宗教之间的斗争,一场关于事务逻辑应该仅仅建立在中间层还是仅仅建立在数据层的斗争;或者说是仅仅在程序中编写查询代码还是全部采用存储过程的争论。当然,这两种方法各有利弊。重要的是我们要考虑什么对我们的程序和系统环境比较重要。所以,让我们来看看存储过程到底是什么,并考虑我们用它来封装T-SQL语句的原因是什么。为何考虑存储过程?也许你经常在程序中利用SqlCommand对象和编写T-SQL语句来完成数据操作,但从没有考虑过寻找更好的地方来存放这些T-SQL语句,而不是将他们与你的数据访问代码混合在一起。也许随着时间的流逝,你的应用程序的功能不断增加,造成了其中存在很多复杂的T-SQL语句代码。存储过程是一种封装这些复杂语句的更好的方法。也许大多数人都对存储过程有所了解,但对于那些不了解它的人,存储过程就是一组许多预先编写好的T-SQL语句序列,并作为一个独立的代码单元保存在数据库中。你可以通过输入参数给它传送运行时信息,也可以通过结果集或输出参数获取返回数据。当存储过程第一次运行时,它就被编译了。它产生了一个执行序列,实质上是一条记录,记录了在存储过程中指定的、用以获得结果的T-SQL语句的执行步骤。之后,这个执行序列便被保存在缓存中以备后用。这将提高存储过程的性能,因为当再一次执行时,存储过程不需要分析代码去执行任务,而是简单地转向保存在缓存中的执行序列。缓存中的内容在SQL Server重新启动之前和在它的内存生命期内都一直有效,它的内存生命期取决于它的最低内存消耗。性能在查询时,这些缓存中的执行序列可以提高存储过程的性能。然而,在最近的两个SQL Server版本中,所有的T-SQL语句批处理都被以执行序列的形式保存在缓存中,而不管它是否存在于存储过程中。因此,在基于此特性上的性能的提高不再是存储过程的卖点。任何采用静态(不经常改变)语法的T-SQL批处理被频繁地提交,以防止它在缓存中的执行序列因为超过内存生命期而消失,这样做同样可以得到很高的性能。注意这里“静态”很 关键,因为即使无关紧要的变化(例如注释的改变)都会导致不与缓存中的执行序列进行匹配。从而也就导致了执行序列的无法重用。可是,存储过程仍旧有它的优点,利用它可以减少网络的数据传输量。你只需要发送如下的指令:EXECUTE stored_proc_name
便可以轻松地执行一系列复杂的操作,而不是那些传统的冗长的T-SQL语句。一个设计良好的存储过程可以显著减少客户端与服务器端的往返通讯,甚至可以压缩至一次调用。另外,使用远程调用(RPC)服务器端的存储过程可以提高执行序列的重用性,从而提高性能。当你使用一个CommandType为StoredProcedure的SqlCommand对象时,存储过程将通过远程调用(RPC)被执行。远程调用排列好参数并调用服务器端的存储过程,它使服务器引擎很容易找到与之匹配的执行序列并方便地提供已经更新的参数值。最后一件需要考虑的事情是,当你准备应用存储过程提高程序的性能时你是否充分发挥了T-SQL的力量。考虑一下你打算怎样操作这些数据。1、你是在做一些基于数据集的操作呢,还是其它一些T-SQL已经支持的很好的操作?如果是这样,那么存储过程是一个不错的选择,虽然直接编写查询语句也可以做到。2、你是在做一些基于数据行的操作呢,还是复杂的字符串操作?如果是这样的话,那么你可以重新考虑直接用T-SQL语句来处理,而不是存储过程。至少在最新的Yukon发布之前,以及合理地与公共语言运行时集成之前是这样的。可维护性与共性提取第二个值得考虑的潜在好处是可维护性。在理想的情况下你的数据库架构不会改变,你的事务规则也不会改变;但在现实中这些是经常发生的。例如:当需要为新的促销活动添加x,y,z表时,你可以通过修改存储过程简单地将这些数据包含近来,而不需要再到你的程序代码中到处寻找需要修改的语句。在存储过程中修改代码对于应用程序来说是透明的,你依旧可以得到相同的销售信息,虽然存储过程的内部实现已经改变了。相对于你修改现有代码,重新测试和配置程序来说,直接修改存储过程更加省时省力。而且,通过提取一些相同的实现方法并将其保存在存储过程中,当应用程序需要通过这些方法访问数据时只需采用相同的操作。你便不用维护散布在许多地方的相同代码了,并保证你的用户可以获得一致的信息。另外一个对维护有好处的是,将T-SQL语句保存在存储过程中也是一种较好的控制版本的方法。你可以利用那些创建和修改存储过程的脚本来做版本控制,就像控制源代码模块的版本一样。通过使用微软提供的Visual SourceSafe和其它一些版本控制工具,你可以很容易地引用和恢复到旧的版本。请不要误解,使用存储过程来提高可维护性并不能避免需要修改数据架构和事务规则的可能。当这些改变过大时,就需要更改存储过程的输入参数与返回值,而且要修改你的前台程序代码例如添加参数、更新GetValue()函数的调用等等。另外需要考虑的问题是,使用存储过程封装事务逻辑限制了你应用程序的可移植性,那样便被束缚在SQL Server上了。如果可移植性对于你的系统环境来说制关重要的话,那么将事务逻辑封装在与关系数据库无关的中间层中是个不错的选择。