我可以理解,由于开销和不便,想要避免使用光标,但似乎有一些严重的光标恐惧症正在发生,人们正在竭尽全力避免使用光标.

例如,有一个问题问,如何使用游标做一些明显无关紧要的事情,并且建议使用带有递归自定义函数的公共表表达式(CTE)递归查询来接受答案,尽管这将可处理的行数限制为32行(由于sql server中的递归函数调用限制).这对我来说是一个可怕的系统生命周期 解决方案,更不用说为了避免使用简单的光标而付出的巨大努力了.

这种疯狂仇恨的原因是什么?是否有"知名权威"发布了针对光标的法令?是不是有什么说不出的邪恶潜伏在诅咒者的心中,腐蚀了子元素们的道德或其他什么?

维基问题,对答案比代表更感兴趣.

相关信息:

SQL Server Fast Forward Cursors

编辑:让我更准确地说:我理解cursors should not be used instead of normal relational operations;这是不需要动脑筋的.我不明白的是,人们会想方设法避免使用光标,比如他们有cooties之类的东西,即使光标是更简单和/或更有效的解决方案.让我困惑的是非理性的仇恨,而不是显而易见的技术效率.

推荐答案

游标的"开销"只是API的一部分.游标是RDBMS的一部分如何在引擎盖下工作的.通常CREATE TABLEINSERTSELECT条语句,实现是明显的内部游标实现.

使用更高级的"基于集合的运算符"将光标结果Bundle 到单个结果集中,这意味着来回的API更少.

游标早于提供一流集合的现代语言.旧的C、COBOL、Fortran等必须一次处理一行,因为没有可以广泛使用的"集合"概念.Java、C#、Python等都有一流的列表结构来包含结果集.

The Slow Issue

在某些圈子里,关系连接是个谜,人们会编写嵌套的游标,而不是简单的连接.我见过真正史诗般的嵌套循环操作,它们被写成了大量的游标.击败RDBMS优化.而且跑得很慢.

简单的SQL重写将嵌套的游标循环替换为联接,一个单一的、扁平的游标循环可以使程序在第100次运行.[他们认为我是优化之神.我所做的只是用连接替换嵌套循环.仍然使用游标.]

这种混乱通常会导致对光标的起诉.然而,问题不在于光标,而是光标的滥用.

The Size Issue

对于真正史诗般的结果集(即,将表转储到文件),游标是必不可少的.基于集合的操作无法在内存中将真正大的结果集具体化为单个集合.

Alternatives

我尽量使用ORM层.但这有两个目的.首先,游标由ORM组件管理.其次,将SQL从应用程序分离到一个配置文件中.并不是说光标不好.对所有这些打开、关闭和获取进行编码并不是增值编程.

Sql相关问答推荐

加入日期表,带有脏日期字段

SQL Server 按从前到后的顺序从记录中减去一个值

MariaDB 中 CAST() 和 COALESCE() 的顺序很重要

Bigquery SQL Multiple Count group-by 在单个查询中

如何识别跨数组列的不同组合,然后在 sql presto 中取消嵌套

SQL - 标记行直到每组的0值

如果其他行有子元素,如何避免选择没有子元素的父母行?

SQL查询,从两个值中列出?

根据其他表中的数据更新和更新数据

在多个数据集中查找相同的行

如何计算给定状态的最后记录?

如何删除具有特定字符的行

Google BigQuery:UNNEST,每个不同的键都变成一列

在指定条件下计算转化率

ORDER BY 首先具有特定值

根据示例结束日期和季度编号计算季度日期

如何在 PostgreSQL 中使用 RETURNING 和 ON CONFLICT?

使用 Python 连接到 Microsoft SQL 服务器

Teradata 中的 ROWS UNBOUNDED PRECEDING 用于什么?

如何跳过sql查询中的前n行