You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server带@与不带@的两种游标声明方式的区别及优劣对比

SQL Server两种游标声明的差异及优劣势对比

两种写法定义

1. 无@前缀的普通游标声明

DECLARE CRS_RQS INSENSITIVE CURSOR FOR
    SELECT pRqsMtr FROM dtRqsMtr
    WHERE pRqs = @pRqs
OPEN CRS_RQS
FETCH NEXT FROM CRS_RQS INTO @pRqsMtr
WHILE (@@Fetch_Status = 0) AND (@@Error = 0)
BEGIN

    -- do some stuff...
    FETCH NEXT FROM CRS_RQS INTO @pRqsMtr
END 
CLOSE CRS_RQS
DEALLOCATE CRS_RQS

2. 带@前缀的游标变量声明

DECLARE @CRS_RQS CURSOR
SET @CRS_RQS = VOID
SET @CRS_RQS = CURSOR FOR
    SELECT pRqsMtr FROM dtRqsMtr
    WHERE pRqs = @pRqs
OPEN @CRS_RQS
FETCH NEXT FROM @CRS_RQS INTO @pRqsMtr
WHILE (@@Fetch_Status = 0) AND (@@Error = 0)
BEGIN

    -- do some stuff...
    FETCH NEXT FROM @CRS_RQS INTO @pRqsMtr
END 
CLOSE @CRS_RQS
DEALLOCATE @CRS_RQS

核心区别

  • 类型属性不同:无@的是SQL Server原生游标对象,属于数据库对象范畴;带@的是游标类型局部变量,和普通的@int、@varchar类型变量属性完全一致。
  • 作用域不同:普通游标默认作用域为当前会话的当前批处理,声明时加GLOBAL关键字可扩展到整个会话,跨批处理也可访问;游标变量作用域严格限制在当前声明的批处理、存储过程、自定义函数内部,超出范围自动失效。
  • 资源回收规则不同:普通游标必须显式执行DEALLOCATE命令才会释放占用的资源,漏写会导致资源一直占用到会话结束;游标变量作为局部变量,作用域结束后系统会自动回收资源,即使漏写DEALLOCATE也不会出现长期资源泄漏。
  • 使用灵活性不同:游标变量可多次赋值绑定不同的查询逻辑,支持作为存储过程/函数的输出参数传递;普通游标一旦声明就无法修改绑定的查询,也不能作为参数传递。

哪一种更优

绝大多数业务场景下,带@前缀的游标变量更推荐使用:

  • 资源管理更安全,大幅降低遗忘释放导致的资源泄漏风险
  • 作用域更可控,不会出现多批处理同名游标冲突的问题
  • 功能灵活性更高,支持参数传递、重复赋值的场景
    只有当你确实需要在同一个会话的多个批处理中复用同一个游标时,才需要使用普通游标,这类场景在实际开发中非常少见。

内容的提问来源于stack exchange,提问作者ghiboz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 19:48:02