什么时候绝对需要程序查询?


8

我知道我们倾向于不惜一切代价避免SQL Server中的游标和循环,但是在某些情况下您绝对需要过程查询,而基于集合的查询却不会为您提供结果?

我了解两者之间的区别,只是我从未遇到过需要使用游标的情况。我想知道是否有这种情况。

Answers:


9

以我的经验,我遇到过几次必须采取程序/迭代方法的情况。

API仅允许单行操作

如果我想以编程方式将具有500个类型错误的列的表中的数据类型从实数更改为十进制,就像SO问题所要求的那样,游标是一种很好的方法,因为DDL不允许在单个语句中更改多个列。

基于集合的不缩放

如果您有《SQL Server MVP深入研究》一书,Hugo Kornelis的第4章“基于集合的迭代:第三种选择” 对于基于游标/集合的组合操作有一些很好的用例。本章作者引用的两个经典问题是“ 运行总计”和“ 装箱”

我将基于集合的迭代方法成功地用于上一个工作所继承的设计不良的流程。简而言之,有一个过程每年必须更新50-75M行,而尝试一次更新一次会浪费我们的日志。通过将更新分块成小批的N行,它使日志得以保持,并且实际上比上一年(仅分配更多的磁盘空间)快得多。


6

当无法完成某件事时,请基于集合。

出血当然很明显。但是请注意,“不基于集合”和使用程序解决方案的人有所不同,因为他们不了解集合或不知道如何使用基于集合的代码。

过程代码的一个示例是每行发送一封电子邮件,每行具有不同的内容

许多DBA使用的SQL代码都是过程性的。例如,在数据库和表上循环(CURSOR或WHILE:无差异)以重建索引和更新统计信息。

一些SQL构造允许在集合的上下文中进行逐行处理,例如在SO上这样进行CROSS APPLY:为每个FK选择SELECT TOP 5行(不过也请注意ROW_NUMBER()解决方案)

编辑:扩展@billinkc的答案...

CROSS APPLY允许使用具有“单行API”的UDF进行基于集合的操作


2

我知道您在问有关SQL Server的问题,但是在Oracle世界中(过去),临时表的成本很高,因此基于游标的过程和触发器更快,并且服务器的“成本”更低。在SQL Server中,游标的开销通常比临时表高得多,因此不鼓励编写基于游标的代码。我敢肯定,这些差异在过去十年中已经消除。

为了应对这些情况,大多数人都有避免将业务逻辑放入数据库中的一般规则。如果您绝对可以永远总是这样做,那么在T-SQL和PL / SQL中都不会有程序逻辑的任何理由。关系数据库擅长基于集合的逻辑。大多数现代编程语言都擅长过程逻辑。最好利用每个人的特长。

我使用过的一些审计触发器对于必须检查的内容以及必须在何处进行更新/记录的规则有相当复杂的规则。有些是用于使报表系统与事务系统保持同步(这不是我的选择,但他们希望这样做)。有些是用于配方系统的。处方是药品的清单,对于每个保险公司,药品将/将不承保什么,如果规定了drug_X,则哪些替代品将被保险承保。在同一家保险公司,不同的团体保单也要为不同的药物付款。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.