游标与重复的代码/逻辑

时间:2009-07-06 23:41:26

标签: database database-design stored-procedures cursors

我听说使用游标并不好,因为它们对DBMS“不自然”并且它们提供了不良的性能。
但想象一下以下情况:我有一个存储过程,我需要为来自法国的每个客户调用此存储过程(例如)。我有几个选项,例如使用游标,在一个查询中写入所有内容,并从客户端应用程序为每个客户调用存储过程。
如果我在一个查询中写入所有内容 - 它很可能会从现有的存储过程中复制代码/逻辑/整个查询。它看起来像一个“臭的方法”(如果你读“重构”一书)给我。逻辑不再包含在一个地方。

您怎么看?

PS。任何描述光标坏或坏的原因的链接都是受欢迎的。

5 个答案:

答案 0 :(得分:1)

如果你承诺在数据库上以存储过程的形式拥有业务逻辑,那么光标也不错。

假设您有一个非常标准的客户端 - 服务器 - 数据库架构,那么将逻辑移出数据库并进入应用服务器可能更好。这有几个好处:

  1. 更好的可扩展性。添加应用服务器比数据库服务器更容易/更便宜。
  2. 集中业务逻辑。业务逻辑遍布全局的应用程序难以维护。

答案 1 :(得分:1)

另请注意,游标性能将从RDBMS到RDBMS不等。

但是,我认为可以证明游标 对SQL数据库来说是不自然的(并且有一些专家会讨论这个问题)。如果你考虑一下,游标可以被认为是一个迭代器(如果你真的想要讨厌的话,甚至是一个指针)。虽然迭代器在过程语言中运行良好,但它们并不适合像SQL这样的声明性语言。

现在,我还没有真正使用游标来同意或不同意这种思路。但我会说,当我考虑它时,我真的不会想到我写过的任何通过使用光标简化的查询(并不是说它们不存在)。

答案 2 :(得分:1)

有时候光标是正确使用的工具。还有一些时候,检索整个查询并将其作为一组进行操作会更好。

SQL内置了很多面向集合的操作。例如,UPDATE可以对表中的整个行进行操作。如果有WHERE子句,那些将被更新的行。更新可以使用上下文敏感的子查询和CASE结构,以便以看似不同的方式更新不同的行,从而提供了很大的灵活性。

将一个巨大的数据转换表示为单个UPDATE对于刚刚开始加速SQL的程序员来说似乎是一项艰巨的任务。声明游标,循环返回的行,将每行作为记录处理,并在一次处理时恢复为一个记录要容易得多。只要你对数据库的参与仍然是“精简”,那对你来说就足够了。

但是,如果您希望构建工业级数据库,那么您应该学习如何根据行集来操作数据,而不是一次只能处理一行。你会获得更好的表现。也许更重要的是,您可以更清楚地了解基础业务规则与您编写的代码之间的关系。

在设计良好的数据库中操作数据集比在设计不佳的数据库中操作容易得多。如果您只是想加快数据库设计速度,并且同时加快SQL查询的速度,您可能希望找一位导师为您的数据库设计提供建议。如果您不这样做,您可能很难学习面向集合操作的强大功能和简单性。

而且,有时候你会使用游标。

答案 3 :(得分:0)

根据您的商店过程的编写方式,如果您使用的是SQL Server,则可以将其转换为函数。使用函数,您可以单独执行以下操作:

SELECT uf_MyFunction(customer_id, customer_name, customer_address) FROM Customer

将其应用于每个客户记录

答案 4 :(得分:0)

游标不一定是坏的,只是在大多数情况下你的直觉告诉你使用游标,有一种更高效的方法来使用声明式或基于集合的方法来做同样的事情。如果你发布你的proc的细节,我打赌你会得到一些很好的建议,如何通过一个存储的proc调用和没有光标来做你需要的。