Skip to content

sql-cursor-functions

在 SQL 中,游标(cursor)是一个数据库对象,允许你逐行遍历结果集中的行。它充当指向单行的指针,从而实现逐行处理,这与 SQL 基于集合的特性相反。

在现代 SQL 开发中,游标通常被视为一种反模式,应尽量避免。SQL 旨在实现强大、高效的基于集合的操作(一次性操作所有行)。游标强制采用过程化的逐行方法(RBAR - Row By Agonizing Row,即“逐行痛苦处理”),这通常是缓慢、低效的,并且更难阅读和维护。

仅在无法通过基于集合的逻辑执行的任务中,才将游标作为最后的手段,例如复杂的管理任务、逐行执行动态 SQL,或与需要游标的遗留系统进行交互。

大多数看似需要游标的问题,都可以通过现代 SQL 功能更高效地解决,例如:

  • 窗口函数(Window Functions): 用于依赖其他行的计算,如累计总和、排名和移动平均。
  • 公用表表达式(CTEs - Common Table Expressions): 用于将复杂查询分解为逻辑上可读的步骤。
  • 临时表(Temporary Tables): 用于在复杂的、多步骤处理中存储中间结果。

假设我们想计算销售额的累计总和。以下是使用窗口函数实现的高效现代方法:

-- 现代的、基于集合的方法(高效)
SELECT
SaleDate,
Amount,
SUM(Amount) OVER (ORDER BY SaleDate) AS RunningTotal
FROM Sales;

基于游标的方法(仅为演示目的而显示)则更加冗长、复杂,并且在大型数据集上明显更慢。

以下描述的函数是 Microsoft SQL Server 的 Transact-SQL (T-SQL) 方言特有的。它们返回有关游标状态的信息。

所有游标函数都是非确定性的,这意味着它们每次被调用时都可能返回不同的结果,即使输入值相同,因为它们依赖于游标的当前状态。

函数描述
@@CURSOR_ROWS返回上一个已打开游标的行数。如果没有打开游标或上一个游标已关闭或解除分配,则返回 0。
@@FETCH_STATUS返回针对当前任何打开游标发出的最后一个 FETCH 语句的状态。成功提取返回 0,提取超出结果集末尾返回 -1,缺少行返回 -2。
CURSOR_STATUS一个标量函数,通过名称或游标变量指示特定游标的状态。帮助确定游标是打开、关闭还是不存在。

虽然了解游标的用途很有帮助,尤其是在遇到遗留代码时,但你的学习重点应该放在掌握基于集合的操作和现代 SQL 功能上。这将带来更高效、可扩展和可维护的解决方案。