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

例如,有一个问题问,如何使用游标做一些明显无关紧要的事情,并且建议使用带有递归自定义函数的公共表表达式(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等都有一流的列表 struct 来包含结果集.

The Slow Issue

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

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

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

The Size Issue

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

Alternatives

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

Sql相关问答推荐

在SQL Server中使用LEFT连接包含特定记录

如何查询一个名称是根据PL/pgSQL函数结果构建的表?

通过 Select 值的顺序进行排序ClickHouse

R中对Arrow duckdb工作流的SQL查询

找到最新的连线

按分类标准检索记录

基于多参数的SQL Server条件过滤

Oracle分层查询-两条路径在末尾合并为一条

日期逻辑(查找过go 90 天内的第一个匹配行)

匹配 H[0-9][0-9] 但不匹配除字母 H 之外的任何字母

如何在 SQL 中将两行(或多行)jsonb 数组合并为一行

PostgreSQL中如何提取以特定字符开头的字符串中的所有单词?

在Snowflake中如何使用SQL对版本字符串进行排序?

为什么在事务中未被后续使用的CTE执行SELECT...FOR UPDATE无效?

使用in和and运算符过滤记录的条件

连续期间的缺口

超过100名员工的连续行

连接表时避免重复

SQL Server Where 条件

使用 JSON_BUILD_OBJ 从 Postgres 返回 JSON