我应该在这里使用SQL游标吗?

时间:2009-08-18 14:30:26

标签: sql sql-server concurrency performance cursor

我最近读到过应该如何避免使用游标。好吧,我想知道我对它们的使用是否合适。

我正在创建一个可在线工作的脚本引擎(嵌入在页面,服务器端)此脚本引擎将由本产品的“高级”最终用户使用。然而,该产品与数据库非常相似,并且脚本语言类似于C语言,但简化为类似于PHP的地方。对于数据库,我基本上需要这样的语法,因为它是语言中最一致的语法,而最终用户不必手写SQL代码(如果我们要让他们这样做,为什么他们不能跳过脚本引擎作为它的生活更简单)。语法是这样的:

declare DataSet $data("tablename","OtherID="+$oid);
//Dataset(string tablename,string where_clause_addon)
$data["field1"]="the data of field... ";
$data.Next();  
$data["field1"]="The data of the next row";
$data[10]["field1"]="The data of the 10th row";

我通过为每个DataSet创建一个全局游标(我只在应用程序中使用1个连接)然后让全局游标跟踪当前行位置(它也是一个SCROLL和UPDATE游标)来内部控制它。这使我的生活变得更加简单,否则我将被迫编写自己的SQL控件来对抗.Net的糟糕DataReader。

游标的使用是否正常?请注意,包含这些脚本的页面无法在全球范围内访问,仅适用于客户端(因此可能只有3-10个用户同时访问)。

有没有人看到更好的方法来跟踪当前的变量位置? (因为这些能够解决未知模式的表格)

另外,使用这样的游标我会遇到并发问题吗? (我的文档说游标对于连接是全局的,并且每个页面请求都会在现场建立新连接,因此用户不会共享连接)

1 个答案:

答案 0 :(得分:8)

“我最近读到过应该如何避免使用游标。”

无法避免。

“我已经阅读了更多,不一定要避免使用游标,而是游标很慢,只能在某些情况下使用。”

正确 - 在某些情况下。

尽可能使用SQL语句。不要通过打开游标并执行一堆if语句来创建自己的SELECT处理逻辑:使用WHERE子句。不要通过打开游标并读取每一行来发明自己的GROUP-BY处理:使用GROUP BY子句。不要使用嵌套游标循环创建自己的连接算法:使用正确的JOIN子句。

不要使用游标发明自己的SQL。使用SQL。

通常,“不使用游标”的人说“不要使用游标重新发明SQL算法”。这不是一个广泛的,模糊的“不要使用游标”。这是非常具体的建议:“学习SQL,不要通过编写游标循环来解决知识上的空白。”

只要你没有重新发明现有的SQL算法,你就必须必须使用游标。

不要迷恋“避免游标”。在合理的“纯SQL”中做过多的迷恋。

当您用手轻触光标/无光标编程时,不要进行过早优化。只需编写尽可能最好的SQL并尽早并经常对性能进行基准测试。

如果你无法找到最好的SQL,请在这里询问最好的SQL - 不要迷恋游标。