当前位置:  开发笔记 > 编程语言 > 正文

将SQL保存在存储过程与代码中的优缺点是什么

如何解决《将SQL保存在存储过程与代码中的优缺点是什么》经验,为你挑选了17个好方法。

在您的C#源代码或存储过程中保留SQL有哪些优点/缺点?我一直在与一位朋友讨论我们正在开发的一个开源项目(C#ASP.NET论坛).目前,大多数数据库访问都是通过在C#中构建SQL内联并调用SQL Server DB来完成的.所以我试图确定哪个特定项目最好.

到目前为止,我有:

代码中的优点:

易于维护 - 无需运行SQL脚本来更新查询

更容易移植到另一个数据库 - 没有移动到端口

存储过程的优点:

性能

安全

Orion Edward.. 179

我不是存储过程的粉丝

存储过程更易于维护,因为:*无论何时想要更改某些SQL,都不必重新编译C#应用程序

无论如何,当数据类型改变时,或者你想要返回一个额外的列,或者其他什么时,你最终会重新编译它.从您的应用程序下面"透明地"更改SQL的次数总体来说非常小

您最终重用SQL代码.

编程语言,包括C#,有这个神奇的东西,称为函数.这意味着您可以从多个位置调用相同的代码块!惊人!然后,您可以将可重复使用的SQL代码放在其中一个中,或者如果您想获得真正的高科技,您可以使用为您执行此操作的库.我相信它们被称为对象关系映射器,现在很常见.

当您尝试构建可维护的应用程序时,代码重复是您可以做的最糟糕的事情!

同意,这就是为什么storedprocs是一件坏事.将SQL重构和分解(分解成较小的部分)代码转换为函数比SQL更容易?

你有4个网络服务器和一堆使用相同SQL代码的Windows应用程序现在你意识到SQl代码有一个小问题所以你宁愿......在一个地方更改proc或将代码推送到所有在网络服务器上,重新安装所有桌面应用程序(clickonce可能会有所帮助)

为什么您的Windows应用程序直接连接到中央数据库?这似乎是一个巨大的安全漏洞,并且它排除了服务器端缓存的瓶颈.它们不应该通过Web服务或类似于您的Web服务器连接吗?

那么,推送1个新的,或4个新的网络服务器?

在这种情况下,它易于推动一个新的存储过程,但以我的经验,95%的"推变化"影响的代码,而不是数据库.如果你在那个月向网络服务器推送了20件事,并且在数据库中推送了1件,那么如果你将21件事情推送到网络服务器上,那么你几乎不会损失太多,而对数据库则为0.

更容易审查代码.

你能解释一下吗?我不懂.特别是因为sprocs可能不在源代码控制中,因此无法通过基于Web的SCM浏览器访问等等.

更多缺点:

存储过程存在于数据库中,该数据库在外部世界中显示为黑盒子.想要将它们置于源代码控制中的简单事情变成了一场噩梦.

还有一个纯粹的努力问题.如果你试图向你的CEO证明为什么只花费700万美元来建立一些论坛,那么将所有内容分解成一百万层可能是有意义的,但是否则为每一件小事创建一个存储过程只是额外的驴工作效益.



1> Orion Edward..:

我不是存储过程的粉丝

存储过程更易于维护,因为:*无论何时想要更改某些SQL,都不必重新编译C#应用程序

无论如何,当数据类型改变时,或者你想要返回一个额外的列,或者其他什么时,你最终会重新编译它.从您的应用程序下面"透明地"更改SQL的次数总体来说非常小

您最终重用SQL代码.

编程语言,包括C#,有这个神奇的东西,称为函数.这意味着您可以从多个位置调用相同的代码块!惊人!然后,您可以将可重复使用的SQL代码放在其中一个中,或者如果您想获得真正的高科技,您可以使用为您执行此操作的库.我相信它们被称为对象关系映射器,现在很常见.

当您尝试构建可维护的应用程序时,代码重复是您可以做的最糟糕的事情!

同意,这就是为什么storedprocs是一件坏事.将SQL重构和分解(分解成较小的部分)代码转换为函数比SQL更容易?

你有4个网络服务器和一堆使用相同SQL代码的Windows应用程序现在你意识到SQl代码有一个小问题所以你宁愿......在一个地方更改proc或将代码推送到所有在网络服务器上,重新安装所有桌面应用程序(clickonce可能会有所帮助)

为什么您的Windows应用程序直接连接到中央数据库?这似乎是一个巨大的安全漏洞,并且它排除了服务器端缓存的瓶颈.它们不应该通过Web服务或类似于您的Web服务器连接吗?

那么,推送1个新的,或4个新的网络服务器?

在这种情况下,它易于推动一个新的存储过程,但以我的经验,95%的"推变化"影响的代码,而不是数据库.如果你在那个月向网络服务器推送了20件事,并且在数据库中推送了1件,那么如果你将21件事情推送到网络服务器上,那么你几乎不会损失太多,而对数据库则为0.

更容易审查代码.

你能解释一下吗?我不懂.特别是因为sprocs可能不在源代码控制中,因此无法通过基于Web的SCM浏览器访问等等.

更多缺点:

存储过程存在于数据库中,该数据库在外部世界中显示为黑盒子.想要将它们置于源代码控制中的简单事情变成了一场噩梦.

还有一个纯粹的努力问题.如果你试图向你的CEO证明为什么只花费700万美元来建立一些论坛,那么将所有内容分解成一百万层可能是有意义的,但是否则为每一件小事创建一个存储过程只是额外的驴工作效益.



2> Eric Z Beard..:

目前正在讨论其他几个主题.我是存储过程的一贯支持者,尽管正在介绍Linq到Sql的一些好的参数.

在代码中嵌入查询会使您与数据模型紧密相关.存储过程是一种很好的合同编程形式,这意味着DBA可以自由地更改数据模型和过程中的代码,只要保持存储过程的输入和输出所代表的合同即可.

当查询隐藏在代码中而不是在一个易于管理的中央位置时,调整生产数据库可能非常困难.

[编辑]这是另一个当前的讨论



3> huo73..:

在我看来,你不能在这个问题上投票赞成或不赞成.这完全取决于您的应用程序的设计.

我完全投票反对在3层环境中使用SP,在这种环境中你有一个应用服务器.在这种环境中,您的应用程序服务器可以运行您的业务逻辑.如果您另外使用SP,则会开始在整个系统中分发业务逻辑的实现,并且很难清楚谁负责什么.最终,您将得到一个应用程序服务器,除了以下内容之外基本上什么也不做:

(Pseudocode)

Function createOrder(Order yourOrder) 
Begin
  Call SP_createOrder(yourOrder)
End

所以最后你在这个非常酷的4服务器集群上运行你的中间层,每个集群配备16个CPU,它实际上什么都不做!多么浪费!

如果你有一个胖的gui客户端直接连接到你的数据库,或者甚至更多的应用程序,它是一个不同的故事.在这种情况下,SP可以作为某种伪中间层,将您的应用程序与数据模型分离,并提供可控制的访问.



4> Rob Allen..:

代码中的优点:

易于维护 - 无需运行SQL脚本来更新查询

更容易移植到另一个数据库 - 没有移动到端口

实际上,我认为你有倒退.恕我直言,SQL中的代码很难维护,因为:

你最终会在相关的代码块中重复自己

许多IDE中不支持SQL语言,因此您只有一系列未经错误检查的字符串为您执行任务

数据类型,表名或约束中的更改比将新数据库换成整个数据库要普遍得多

随着查询复杂性的增加,您的难度也会增加

并测试内联查询需要构建项目

将Stored Procs视为您从数据库对象调用的方法 - 它们更容易重用,只有一个地方可以编辑,如果您更改数据库提供程序,更改将在您的存储过程中发生,而不是在您的代码中.

也就是说,存储过程的性能提升很小,因为Stu在我之前说过,你不能在存储过程中设置一个断点(尚未).



5> computinglif..:

CON

我发现在扩展你的行为时,在存储过程中进行大量处理会使你的数据库服务器成为一个单一的不灵活点.

但是,如果您有多个运行代码的服务器,那么在程序中执行所有与sql-server相反的操作 可能会允许您扩展更多.当然,这不适用于仅执行常规获取或更新的存储过程,而是适用于执行更多处理(如循环数据集)的存储过程.

PROS

    性能可能值(避免通过DB驱动程序/计划重新创建等进行查询解析)

    数据操作没有嵌入到C/C++/C#代码中,这意味着我可以查看较少的低级代码.单独列出时,SQL不那么冗长,也更容易查看.

    由于分离,人们可以更容易地找到并重用SQL代码.

    在架构更改时更容易更改内容 - 您只需要为代码提供相同的输出,它就可以正常工作

    更容易移植到不同的数据库.

    我可以列出我的存储过程的个人权限,并控制该级别的访问权限.

    我可以将数据查询/持久性代码与我的数据转换代码分开.

    我可以在我的存储过程中实现可更改的条件,并且很容易在客户站点进行自定义.

    使用一些自动化工具将我的模式和语句转换为一起变得更容易,而不是当它嵌入我的代码中时我必须将它们追捕.

    当您在单个文件中包含所有数据访问代码时,确保数据访问的最佳实践更容易 - 我可以检查访问非性能表的查询或使用更高级别序列化的查询或在代码中选择*等.

    当一个文件中列出所有模式更改/数据操作逻辑更改时,它变得更容易找到.

    当SQL位于相同位置时,对SQL进行搜索和替换编辑会变得更容易,例如,为所有存储过程更改/添加事务隔离语句.

    我和DBA的家伙发现,当DBA必须审查我的SQL内容时,拥有一个单独的SQL文件更容易/更方便.

    最后,您不必担心SQL注入攻击,因为您的团队中的某些懒惰成员在使用嵌入式sqls时未使用参数化查询.



6> Stu..:

存储过程的性能优势通常可以忽略不计.

存储过程的更多优点:

防止逆向工程(当然,如果使用加密创建)

更好地集中数据库访问

能够透明地更改数据模型(无需部署新客户端); 如果多个程序访问相同的数据模型,则特别方便



7> Rick..:

我落在代码方面.我们构建了所有应用程序(包括Web和客户端)使用的数据访问层,因此从这个角度看它是干的.它简化了数据库部署,因为我们只需要确保表模式是正确的.它简化了代码维护,因为我们不必查看源代码和数据库.

我与数据模型的紧耦合没有太大问题,因为我没有看到真正打破这种耦合的可能性.应用程序及其数据本质上是耦合的.



8> mbillard..:

存储过程.

如果错误滑动或逻辑稍微改变,则不必重新编译项目.此外,它允许从不同的来源访问,而不仅仅是您在项目中编码查询的地方.

我不认为维护存储过程更难,你不应该直接在数据库中编码,而是先在单独的文件中编码,然后你可以在你需要设置的任何数据库上运行它们.


如果您发现自己做出了基本的架构决策以避免重新编译代码,那么在做任何事情之前,建立一个并不完全糟糕的构建过程.这是一个非争论.

9> Matthew Farw..:

存储过程的优点:

更容易审查代码.

耦合较少,因此更容易测试.

更容易调整.

从网络流量的角度来看,性能通常更好 - 如果你有一个游标或类似的游戏,那么就没有多次访问数据库

您可以更轻松地保护对数据的访问,删除对表的直接访问,通过过程强制执行安全性 - 这也允许您相对快速地找到更新表的任何代码.

如果涉及其他服务(例如Reporting Services),您可能会发现将所有逻辑存储在存储过程中而不是代码中更容易,并且必须复制它

缺点:

更难以为开发人员管理:脚本的版本控制:每个人都有自己的数据库,是与数据库和IDE集成的版本控制系统吗?



10> 小智..:

在某些情况下,代码中动态创建的sql可以比存储过程具有更好的性能.如果你创建了一个存储过程(让我们说sp_customersearch)变得非常复杂,因为它必须非常灵活,你可能会在运行时在代码中生成一个更简单的sql语句.

有人可能会说,这只是将一些处理从SQL移动到Web服务器,但总的来说这将是一件好事.

关于这种技术的另一个好处是,如果你正在查看SQL分析器,你可以看到你生成的查询并调试它比看到存储的带有20个参数的proc调用更容易.



11> 小智..:

我喜欢存储过程,不知道有多少次我能够使用存储过程对应用程序进行更改,而该存储过程不会对应用程序产生任何停机时间.

Transact SQL的大粉丝,调整大型查询已被证明对我非常有用.大约6年内没有写过任何内联SQL!



12> Keith..:

你列出了2个针对sprocs的专业点:

表现 - 不是真的.在Sql 2000或更高版本中,查询计划优化非常好,并且已缓存.我确信Oracle等会做类似的事情.我认为不再有针对性能的sprocs了.

安全?为什么sprocs会更安全?除非您拥有一个非常不安全的数据库,否则所有访问都将来自您的DBA或您的应用程序.总是参数化所有查询 - 永远不要在用户输入内联内容,你会没事的.

无论如何,这是性能的最佳实践.

Linq绝对是我现在开展新项目的方式.看到这篇类似的帖子.



13> Guy..:

@Keith

安全?为什么sprocs会更安全?

根据Komradekatz的建议,您可以禁止访问表(对于连接到数据库的用户名/密码组合)并仅允许SP访问.这样,如果有人获取数据库的用户名和密码,他们就可以执行SP,但无法访问表或数据库的任何其他部分.

(当然,执行sprocs可能会为他们提供他们需要的所有数据,但这取决于可用的sprocs.让他们访问表格可以让他们访问所有内容.)



14> SQLMenace..:

这样想吧

你有4个网络服务器和一堆使用相同SQL代码的Windows应用程序现在你意识到SQl代码有一个小问题所以你宁愿......在一个地方更改proc或将代码推送到所有在网络服务器上,重新安装所有桌面应用程序(clickonce可能会有所帮助)

我更喜欢存储过程

对proc进行性能测试也更容易,将它放在查询分析器中设置统计io/time on set showplan_text on和voila

无需运行探查器即可查看正在调用的内容

只是我的2美分



15> John Sheehan..:

我更喜欢在代码中保留它们(使用ORM,而不是内联或临时),因此它们被源代码控制所覆盖,而不必处理保存的.sql文件.

此外,存储过程本身并不安全.您可以使用sproc编写错误查询,就像内联一样容易.参数化内联查询可以像sproc一样安全.



16> 小智..:

使用您的应用程序代码作为它最擅长的:处理逻辑.
使用您的数据库以获得最佳效果:存储数据.

您可以调试存储过程,但您会发现在代码中更容易调试和维护逻辑.通常,每次更改数据库模型时,都将重新编译代码.

此外,具有可选搜索参数的存储过程非常有用,因为您必须事先指定所有可能的参数,并且有时无法进行复杂搜索,因为您无法预测参数将在搜索中重复多少次.


多个应用程序不应对数据库进行相同类型的更改.应该有一个应用程序组件处理单一类型的更改.然后,如果其他人感兴趣,该应用程序应该公开服务.多个应用程序以他们认为合适的方式更改相同的数据库/表是导致应用程序系统和数据库变得无法维护的原因.
当多个应用程序访问同一个数据库,并且数据库受到导入和其他直接访问的影响(将所有价格更新10%)时,逻辑必须位于数据库中,否则您将失去数据库完整性.
"应该有一个应用程序组件处理单一类型的更改" - 该组件可以是存储过程,例如在PL/SQL中.

17> Tom H..:

在安全性方面,存储过程更安全.有些人认为所有访问都是通过应用程序进行的.很多人都忘记的事情是,大多数安全漏洞都来自公司内部.想想有多少开发人员知道应用程序的"隐藏"用户名和密码?

此外,正如MatthieuF指出的那样,由于应用程序(无论是在桌面服务器还是Web服务器上)与数据库服务器之间的往返次数减少,性能可以大大提高.

根据我的经验,通过存储过程抽象数据模型也极大地提高了可维护性.作为过去必须维护许多数据库的人,当面对所需的模型更改时,能够简单地更改一两个存储过程并使更改对所有外部应用程序完全透明,这是一种解脱.很多时候,您的应用程序并不是唯一指向数据库的应用程序 - 还有其他应用程序,报告解决方案等,因此跟踪所有这些受影响的点可能是对表的开放访问的麻烦.

我还将检查放在加号列中,以便将SQL编程放在那些专门研究它的人手中,并使SP更容易隔离和测试/优化代码.

我看到的一个缺点是许多语言不允许传递表参数,因此传递未知数量的数据值可能很烦人,而且某些语言仍然无法处理从单个存储过程中检索多个结果集(尽管在这方面,后者不会使SP比内联SQL更差).

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有