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
相关产品推荐
相关产品推荐

