【问题标题】:Better to use Stored Procedures or SQL in my code for working with data?更好地在我的代码中使用存储过程或 SQL 来处理数据?
【发布时间】:2009-10-26 21:31:00
【问题描述】:

当涉及到 CRUD 操作和数据库 (SQL Server '08) 时,将 SQL 语句写入代码还是使用存储过程更好?为什么?

如下所述,我省略了 LINQ 作为第三个选项。这样做是因为我不熟悉 LINQ。 . .然而。如果 LINQ 是更好的选择,请告诉我我缺少什么。

【问题讨论】:

  • 您缺少一个选项 - 使用 LINQToSql 或 NHibernate 等 ORM。
  • 有人问过这个问题令人作呕
  • @George 或任何人,请提供其他人提出此问题的链接。这似乎是一个很可能的常见问题解答。

标签: .net sql-server stored-procedures


【解决方案1】:

比起将 SQL 嵌入应用程序,我更喜欢存储过程。

一方面,当您在应用程序中直接引用表时,应用程序必须对表具有适当的权限。与仅允许应用程序登录执行某些存储过程相比,这可能会增加安全风险。

另一件事是,如果您需要更改 SQL 查询,您可能需要重新编译和重新部署应用程序。在最简单的情况下,这是微不足道的,但如果您的代码是分布式的和/或如果您有多个不同的应用程序与同一个数据库通信,这可能会很麻烦。现在您必须在多个地方进行更改,即使查询的界面或结果保持不变。

最后,存储过程实际上会强制您强制键入参数(是的,您仍然可以传入由多个值组成的字符串,如果您愿意,您仍然可以使用动态 SQL,但您必须更加努力地做到这一点) .应用程序中的 SQL 在动态构建字符串和将自己暴露于 SQL 注入方面往往存在更多问题。是的,您可以在应用程序代码中构建更好的参数化语句,但坦率地说,根据我的经验,这是例外而不是规则。

【讨论】:

    【解决方案2】:

    在这两者中,一直是存储过程,如果没有其他原因,在生产环境中更改存储过程损坏时比部署新代码更容易。正如克里斯蒂安指出的那样,它不太容易受到注入攻击(非参数化 SQL 对此非常不利)。

    有性能优势,但它们的重要性值得商榷。

    Jeff(StackOverflow 创始人)喜欢 LINQ to SQL,这与使用存储过程不同,但总体上仍然比使用内联代码更安全。

    【讨论】:

    • 另外,使用存储过程可以防止您无意中让自己受到 SQL 注入攻击。
    【解决方案3】:

    存储过程的另一个优点是您不必在表级别授予权限(除非您使用动态 SQl,出于多种原因要避免这种情况)。这意味着您的内部用户不能直接访问这些表,这使得他们不太可能做除了存储过程允许的事情之外的事情。这有助于减少欺诈的可能性。

    存储过程的另一个优点是它们更容易(在我看来)进行性能调整。

    最后,如果您的数据库服务于多个前端,那么存储过程是标准化应用程序之间查询的好方法。

    【讨论】:

      【解决方案4】:

      绝对比将语句定位到代码中更好。

      原因如下:

      1. 代码中的语句 容易受到代码注入的影响 或任何可能影响的安全漏洞 您的代码,而不是存储过程是避免 参数卫生问题。
      2. 存储过程可以管理另一个独立的权限层和 使用 SQL 登录和应用程序的安全性 为您的 Store 过程的每个用户添加策略。
      3. 如果您需要分享一些 应用程序逻辑给其他人,您可以随时管理存储的 程序作为第三方的黑匣子,保护您的数据库。

      这些只是 SQL SP 的一些安全性和更好的实践功能

      【讨论】:

        【解决方案5】:

        取决于你的喜好。

        过去人们喜欢存储过程,因为它们更安全(内联 SQL 语句是通过连接构建的,这使您可以使用 SQL 注入)。它们还有一个额外的好处,即允许您修改数据库而无需修改代码和重新部署。

        最近,参数化查询(使用带参数的查询,而不是通过连接构建它们)已经流行起来。它们提供与存储过程(无 SQL 注入)相同的安全性,并具有将所有代码放在一个位置的额外好处。这使得您需要随着 CRUD 操作更改而更改其他代码元素变得更加明显。

        在这一点上……这是个人喜好。就我个人而言,我更喜欢代码中的参数化查询,所以我不会在众神绿地上追逐代码。

        而且我不是唯一一个(视情况而定)有这种感觉的人,我不可能再重复 Jeff 博文中的所有精彩观点:

        Coding Horror: Who Needs Stored Procedures, Anyways?

        【讨论】:

        • 我目前的大部分工作都在使用参数化查询。诚然,有时我会为我的一次性一次性应用程序硬编码一个连接字符串。
        • 如果您使用参数化查询,则无需担心 SQL 注入。安全参数为空。
        • 安全与偏好无关。与 SP 相比,SQL 参数化查询是有限的
        【解决方案6】:

        如果归结为在代码中编写 sql 与使用存储过程,那么请使用存储过程......它们至少更安全。

        在你的代码中使用 sql,它看起来很乱,你真的很容易受到 sql 注入攻击。

        另一方面,除非您真的需要使用存储过程,否则我建议您考虑使用某种 ORM。

        【讨论】:

          【解决方案7】:

          存储过程和 CRUD 对我来说没有多大意义,尤其是在 R(读取)的情况下

          无法查询存储过程。我的意思是你不能投影存储过程(只返回一些可能的列)也不能选择存储过程(只返回一些行)和我个人最喜欢的,你不能加入两个存储的一起办理手续。

          综上所述,您将拥有大量由 CREATE PROCEDURE 包裹的专用查询

          保存执行计划的胜利不再是存储过程的专有功能。参数化查询也受益于过程缓存。

          安全性的胜利并不是存储过程的独有特性——视图也提供了一定的安全性。但是当我们谈论安全性时——SQL 是守门人吗?也许它是,或者更可能是它的业务引擎

          在基本的客户端服务器时代,客户端是某种 VB 3 应用程序,它直接连接到 SQL Sever,那么这个讨论将是一个没有实际意义的问题——存储过程等等。但我们不再构建这类应用了(是吗?)

          【讨论】:

          • 我不知道应用程序开发人员在很多地方决定安全性、业务逻辑、哪些表应该加入什么、优化等。也许如果 DBA 也在编写应用程序代码,但这在今天是罕见的......仅仅因为开发人员可以编写所有 SQL 查询并不意味着他/她应该。
          • 安全可以成为 DBA 领域的日子已经一去不复返了。在过去 10 年中,我参与的所有应用程序都使用了某种应用程序服务,它汇集了与数据库服务器的连接。因此,dba 无法区分调用者,所以不管你喜欢与否(我知道没有一个 dba 喜欢它)安全性不再由他们实现。
          【解决方案8】:

          动态 SQL 和存储过程之间的选择可能总是有争议,但我发现这是我读过的最有说服力的论点:

          Stored procedures are bad, m'kay?(作者:Frans Bouma)

          特别是对于 CRUD,很难证明存储过程更好。虽然动态 SQL 确实有缺点,但一个好的 ORM 和/或 Linq 可以摆脱其中的大部分。如果您在体面的项目中都尝试过这两种方式,如果有机会,请务必按照您的个人喜好进行。

          【讨论】:

            【解决方案9】:

            我曾经是一个铁杆的存储过程倡导者,但最近我改变了立场。

            存储过程的一个问题是所有查询都必须提前定义,并且所有查询都需要在存储过程中定义。比如说,我想查询某个名字的用户,而姓不是以“a”开头的,而且还没有存储过程这样做(可能没有),我必须写一个新的一。这是一种用于处理一项特定功能的新存储过程。在我从事的上一个数据库项目中,由于查询相同数据的新方法,存储过程的数量不断增加。

            在我当前的应用程序中,我根据 lambda 表达式动态生成 SQL 查询。这允许我查询域对象上的任何属性组合,并让数据访问层将其转换为有效的 SQL 查询。

            我现在的代码少了很多,更容易理解,最重要的是,实现新功能要快得多。然而,我有时会使用存储过程来插入和更新数据,因为它们允许我验证无效数据,并在数据无效时中止事务。

            安全隐患如何?传统上,存储过程提供了安全优势,因为您可以将表隐藏起来,只公开存储过程,并指定哪个用户可以访问哪个存储过程。但是谁再创建客户端直接访问数据库的应用程序呢?

            我总是会在数据库顶部有某种应用程序层作为服务在某处运行(Web 服务、Windows 服务、Web 应用程序等),并且该服务将实现安全性。没有用户可以直接访问数据库。

            【讨论】:

              猜你喜欢
              • 2016-07-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-21
              • 1970-01-01
              • 2021-08-28
              • 1970-01-01
              • 2011-02-03
              相关资源
              最近更新 更多