假设您无论出于何种原因无法使用LINQ,将查询放在存储过程中是一种更好的做法,还是对数据库执行即席查询(例如,为了参数而使用SQL Server)这是一种很好的做法?

===============>>#1 票数:93 已采纳

根据我编写WinForms客户端/服务器应用程序的经验,这些是我得出的简单结论:

使用存储过程:

  1. 对于任何复杂的数据工作。 如果您要做一些真正需要游标或临时表的事情,那么在SQL Server中执行它通常是最快的。
  2. 当您需要锁定对数据的访问时。 如果您不向用户(或角色或其他)提供表访问权限,则可以确保与数据交互的唯一方法是通过您创建的SP。

使用即席查询:

  1. 对于CRUD,当您不需要限制数据访问时(或以其他方式这样做)。
  2. 对于简单的搜索。 为一堆搜索标准创建SP是一件痛苦的事情并且难以维护。 如果您可以生成相当快速的搜索查询,请使用它。

在我的大多数应用程序中,我都使用了SP和ad-hoc sql,虽然我发现我使用的SP越来越少,因为它们最终成为像C#一样的代码,只是更难以进行版本控制,测试和维护。 我建议使用ad-hoc sql,除非你能找到一个特定的理由不这样做。

===============>>#2 票数:27

我不能说除SQL Server以外的任何其他内容,但除非你在6.5或更早版本,否则性能参数在那里并不显着。 SQL Server已经缓存了大约十年的临时执行计划。

===============>>#3 票数:13

存储过程表示封装对数据库采取的操作的软件合同。 可以更改过程中的代码,甚至数据库本身的模式,而不会影响已编译的已部署代码,只需使过程的输入和输出保持不变即可。

通过在应用程序中嵌入查询,您可以将自己与数据模型紧密结合。

出于同样的原因,简单地创建仅针对数据库中每个表的CRUD查询的存储过程也是不好的做法,因为这仍然是紧密耦合。 相反,程序应该是庞大的粗粒度操作。

从安全角度来看,最好从应用程序中禁用db_datareader和db_datawriter,并且只允许访问存储过程。

===============>>#4 票数:12

我认为这是必须维护数据库的人和开发用户界面的人之间的基本冲突。

作为数据人,我不会考虑使用通过adhoc查询访问的数据库,因为它们很难有效地调整或管理。 我如何知道对架构的更改会产生什么影响? 此外,出于安全原因,我认为不应该授予用户直接访问数据库表的权利(我不仅仅意味着SQL注入攻击,而且因为它是一个基本的内部控制,不允许直接权限并要求所有用户只使用为应用程序设计的过程。这是为了防止可能的欺诈。任何允许直接插入,更新或删除表权限的金融系统都存在欺诈的巨大风险。这是一件坏事。)。

数据库不是面向对象的,从面向对象的角度来看似乎很好的代码从数据库的角度来看可能非常糟糕。

我们的开发人员告诉我们他们很高兴我们所有的数据库访问都是通过procs,因为它可以更快地修复以数据为中心的bug,然后在生产环境中运行proc而不是创建代码的新分支并重新编译和重新加载到生产。 我们要求所有的proc都处于颠覆状态,所以源控制根本不是问题。 如果它不在Subversion中,它将定期被dbas删除,因此使用Source Control没有阻力。

===============>>#5 票数:6

存储过程绝对是可行的方法......它们是经过编译的,具有执行计划,您可以对它们进行权限管理。

我不理解存储过程中的整个源代码控制问题。 如果只是你有点自律,你绝对可以控制它们。

始终以.sql文件开头,该文件是存储过程的源。 编写代码后,将其置于版本控制中。 下次要编辑存储过程时,从源控件获取它而不是数据库。 如果你遵循这个,你将拥有与你的代码一样好的源代码控制。

我想在这里引用Oracle的Tom Kyte ......这是他在编写代码的地方的规则......虽然有点无关但很好知道我猜。

  1. 从PL / SQL中的存储过程开始......
  2. 如果您认为使用PL / SQL中的存储过程无法完成某些操作,请使用Java存储过程。
  3. 如果您认为使用Java存储过程无法完成某些操作,请考虑使用Pro * c。
  4. 如果您认为使用Pro * C无法实现某些功能,您可能需要重新考虑完成所需的工作。

===============>>#6 票数:4

在我们的应用程序中,有一层代码提供查询的内容(有时是对存储过程的调用)。 这允许我们:

  • 轻松拥有版本控制下的所有查询
  • 为不同的数据库服务器进行每个查询所需的更改
  • 通过我们的代码消除重复相同的查询代码

访问控制是在中间层而不是在数据库中实现的,因此我们不需要存储过程。 这在某些方面是即席查询和存储过程之间的中间道路。

===============>>#7 票数:3

从另一篇文章回答:存储过程更易于维护,因为:

  • 无论何时想要更改某些SQL,都不必重新编译C#应用程序
  • 您最终重用SQL代码。

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

当您发现需要在多个位置更正的逻辑错误时会发生什么? 您更容易忘记更改复制和粘贴代码的最后一个位置。

在我看来,性能和安全性增益是一个额外的优势。 您仍然可以编写不安全/低效的SQL存储过程。

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

编写用于在另一个DB中创建的所有存储过程并不是很困难。 事实上 - 它比导出表更容易,因为没有主要/外键需要担心。

===============>>#8 票数:3

两者都有说服力的论据 - 存储过程都位于中央存储库中,但是(可能)难以迁移,并且即席查询更容易调试,因为它们与您的代码一样,但它们也很难在码。

存储过程更有效的论点不再存在。 链接文字

对存储过程和动态查询执行谷歌会以任何方式显示正确的参数,可能最适合您做出自己的决定......

===============>>#9 票数:3

应该尽可能多地使用存储过程,如果您将SQL编写成代码,那么您已经为未来的头痛做好了准备。 编写SPROC需要大约相同的时间,就像在代码中编写SPROC一样。

考虑一个在中等负载下运行良好的查询,但一旦进入全时生产,您的优化查询就会破坏系统并使其爬行。 在大多数SQL服务器中,您不是唯一使用它的应用程序/服务。 你的申请现在已经把一群愤怒的人带到你家门口。

如果您在SPROC中有疑问,那么您也可以让友好的DBA通过重新编译或破坏您的应用来管理和优化。 记住DBA是这个领域的专家,他们知道该做什么而不做。 利用他们的更多知识是有道理的!

编辑:有人说重新编译是一个懒惰的借口! 是的,让我们看看当你不得不重新编译和部署你的应用程序到1000个桌面时你感觉有多懒,这都是因为DBA告诉你,你的ad-hoc查询占用了太多的服务器时间!

===============>>#10 票数:2

需要考虑的一些事项: 谁需要存储过程,无论如何?

显然,这是您自己的需求和偏好的问题,但在面向公众的环境中使用即席查询时要考虑的一个非常重要的事情是安全性。 始终对它们进行参数化,并注​​意SQL注入攻击等典型漏洞。

===============>>#11 票数:2

有人说重新编译是一个懒惰的借口! 是的,让我们看看当你不得不重新编译和部署你的应用程序到1000个桌面时你感觉有多懒,这都是因为DBA告诉你,你的ad-hoc查询占用了太多的服务器时间!

如果您将1000台桌面直接连接到数据库,它是否是良好的系统架构?

===============>>#12 票数:1

存储过程很棒,因为它们可以在不重新编译的情况下进行更改。 我会尝试尽可能多地使用它们。

我只对基于用户输入动态生成的查询使用ad-hoc。

===============>>#13 票数:1

由于其他人提到的原因而进行处理,并且使用探查器或部分proc更容易调整proc。 这样您就不必告诉某人运行他的应用程序以找出发送到SQL服务器的内容

如果您确实使用即席查询,请确保它们已参数化

===============>>#14 票数:1

参数化的SQL或SPROC ......从性能角度来看无关紧要......您可以查询优化任何一个。

对我来说,SPROC的最后一个好处是我可以通过仅授予执行sprocs的登录权限来消除大量SQL权限管理...如果使用Parametized SQL,则使用您的连接字符串的登录具有更多权限(编写任何内容)例如,他们有权访问的其中一个表上的select语句。

我仍然更喜欢Parametized SQL ...

===============>>#15 票数:1

我没有找到使用即席查询的任何令人信服的论据。 特别是与您的C#/ Java / PHP代码混淆的那些。

===============>>#16 票数:1

sproc性能参数没有实际意义 - 3个顶级RDBM使用查询计划缓存并且已经有一段时间了。 它已被记录......或者仍然是1995年?

但是,在您的应用程序中嵌入SQL也是一个糟糕的设计 - 对于许多人来说,代码维护似乎是一个缺失的概念。

如果一个应用程序可以从头开始使用ORM(绿地应用程序之间很少而且很少!),这是一个很好的选择,因为您的类模型驱动您的数据库模型 - 并节省了大量时间。

如果ORM框架不可用,我们采用混合方法创建SQL资源XML文件,以便在需要时查找SQL字符串(然后由资源框架缓存它们)。 如果SQL需要在代码中完成任何小的操作 - 如果需要主要的SQL字符串操作,我们重新考虑这种方法。

这种混合方法有助于开发人员轻松管理(可能我们是少数,因为我的团队足够聪明,可以阅读查询计划),部署是SVN的简单结账。 此外,它使切换RDBM更容易 - 只需换出SQL资源文件(当然不像ORM工具那么简单,但连接到遗留系统或不支持的数据库)

===============>>#17 票数:0

存储过程作为代码块工作,因此代替adhoc查询它可以快速工作。 另一件事是存储过程给出重新编译选项,在adhoc查询中,你只是将这个用于存储过程的SQL的最佳部分。

一些结果查询和存储过程是不同的,这是我的个人exp。 使用cast和covert函数进行检查。

必须使用大型项目​​的存储过程来提高性能。

我的项目中有420个程序,对我来说工作正常。 我在这个项目上工作了3年。

因此,只使用任何交易的程序。

===============>>#18 票数:0

取决于你的目标是什么。 例如,如果要检索项目列表并在应用程序的整个运行期间发生一次,则可能不值得使用存储过程。 另一方面,重复运行并且执行(相对)长时间的查询是数据库存储的理想选择,因为性能会更好。

如果您的应用程序几乎完全位于数据库中,那么存储过程就很简单。 如果您正在编写一个只对数据库有重要意义的桌面应用程序,那么即席查询可能是更好的选择,因为它可以将您的所有代码保存在一个位置

@Terrapin:我认为你断言你不需要重新编译应用程序来进行修改这一事实使得存储过程成为一个更好的选择。 可能有理由选择存储过程而非ad-hoc查询,但在没有任何其他令人信服的情况下,编译问题似乎是懒惰而不是真正的原因。

===============>>#19 票数:0

我的经验是,根本不应该写入90%的查询和/或存储过程(至少是手工编写)。

应以某种方式自动生成数据访问。 您可以决定是在编译时静态生成过程还是在运行时动态生成过程,但是当您想要向表中添加列(属性到对象)时,您应该只修改一个文件。

===============>>#20 票数:0

我更喜欢在程序代码中保留所有数据访问逻辑,其中数据访问层执行直接的SQL查询。 另一方面,数据管理逻辑我以触发器,存储过程,自定义函数等形式放入数据库。 我认为值得数据库处理的一个例子是数据生成 - 假设我们的客户有FirstName和LastName。 现在,用户界面需要一个DisplayName,它来自一些非平凡的逻辑。 对于这一代,我创建了一个存储过程,然后每当更新行(或其他源数据)时由触发器执行。

似乎有一种常见的误解,即数据访问层是数据库,关于数据和数据访问的一切都在那里“只是因为”。 这是完全错误的,但我看到很多设计源于这个想法。 不过,也许这是一个当地的现象。

在看到如此多设计糟糕的SP之后,我可能只是关闭了SP的想法。 例如,我参与的一个项目为每个表和他们遇到的每个可能的查询使用了一组CRUD存储过程。 在这样做时,他们只是添加了另一个完全无意义的层。 想想这样的事情是痛苦的。

===============>>#21 票数:0

这些天我几乎没有使用存储过程。 我只将它们用于复杂的SQL查询,这些查询无法在代码中轻松完成。

其中一个主要原因是因为存储过程与OR映射器不兼容。

这些天我认为你需要一个很好的理由来编写一个不使用某种OR映射器的业务应用程序/信息系统。

===============>>#22 票数:-1

如果您将1000台桌面直接连接到数据库,它是否是良好的系统架构?

不,它显然不是,它可能是一个糟糕的例子,但我认为我试图做的一点很明确,你的DBA照顾你的数据库基础设施这是他们的专业知识,填充SQL代码锁定了他们的大门和他们的专业知识。

  ask by community wiki translate from so

未解决问题?本站智能推荐: