2010-03-08 62 views
1

我继承了一个数据库,其中包含大量的游标,并且从我读的游标,游标以及非常慢且资源耗尽的数据库中。我想删除这些如果possbile和替换别的东西。我熟悉CTE,但是想知道WHILE 1 = 1循环内的CTE是否是最佳做法?什么是SQL游标的替代方法

任何想法?

回答

3

你应该看到真的删除任何类型的循环。如果游标可以重写为基于集合的语句(不循环),那么这就是你应该做的。

将游标转换为另一种形式的循环可以减少开销,但仍不能解决性能问题。

当然,有时有需要做循环 - 但是你一般应尽量mimimise那些到最低限度

+0

不幸的是,情况是需要一个循环,但是一个WHILE循环可以通过游标吗? – 2010-03-08 12:53:05

+0

@Ardman - 如果你确实需要一个循环,那么你没有太多的选择。滚动你自己的WHILE循环可以减少开销并且是使用游标的替代方法,但是我没有任何特定的性能比较。 – AdaTheDev 2010-03-08 13:32:19

+0

只要我知道我没有通过使用我自己的WHILE循环来破坏任何SQL规则,那我就是一个快乐的人。谢谢。 – 2010-03-08 14:00:57

1

如果你发现很多游标,它往往指向一个贫穷的SQL开发人员在编写他的SQL代码时过于程序化。

尝试找到可以将过程式代码转换为SQL自己的基于集合的范例的区域。

1

为什么你认为你需要循环,这是必要的极少。游标在做什么?没有更具体的例子就很难提供帮助。

我有一些建议,而不是使用values子句插入一个游标,而是使用基于集合插入的游标中的select来代替。 (更新和删除也可以通过加入您在光标选择中选择的数据来完成,而不是一次一个记录)

如果您正在对特定数据元素进行特殊处理,则CASE语句通常是更好的,基于集合的方式来处理同样的事情。

如果您决定是更新还是插入,请查看MERGE。

由于您的游标正在调用存储过程,因此您的开发人员在不恰当的情况下重新使用代码时做出了糟糕的选择。但是,在SQL Server 2008中,现在您有一个新的选项可以将表作为变量发送到存储过程,因此您可以将该过程重写为基于集并且不处理单个记录。那么你不再需要光标。如果你这样做,你将需要检查它被用来确保单个记录从同一个proc插入的地方仍然正常工作。没有说你不能发送一个单行表,但调用代码将发送正确的表参数,而不是十个单独的字段。或者你可以通过放弃你调用的存储过程并编写一个基于集合的插入来处理这个问题。

业务逻辑几乎肯定可以用CASE语句处理。

+0

基本上,他们选择的数据,然后在那里有一些业务逻辑,并会调用另一个存储过程插入数据依赖于选择标准。 – 2010-03-08 14:33:27

相关问题