T-SQL 游标名称的作用域
Transact-SQL 游标名称的作用域
Microsoft® SQL Server™ 2000 支持 DECLARE CURSOR 语句上的 GLOBAL 和 LOCAL 关键字以定义游标名称的作用域。GLOBAL 指定游标名称对连接是全局性的。LOCAL 指定游标名称对含有 DECLARE CURSOR 语句的存储过程、触发器或批处理是局部性的。
在 Microsoft® SQL Server™ 7.0 版之前的版本中,Transact-SQL 游标的名称对连接而言是全局的。可以执行一个创建游标的存储过程,然后调用另一个存储过程从此游标中提取行:
USE pubs
GO
CREATE PROCEDURE OpenCrsr AS
DECLARE SampleCrsr CURSOR FOR
SELECT au_lname
FROM authors
WHERE au_lname LIKE 'S%'
OPEN SampleCrsr
GO
CREATE PROCEDURE ReadCrsr AS
FETCH NEXT FROM SampleCrsr
WHILE (@@FETCH_STATUS <> -1)
BEGIN
FETCH NEXT FROM SampleCrsr
END
GO
EXEC OpenCrsr /* DECLARES and OPENS SampleCrsr. */
GO
EXEC ReadCrsr /* Fetches the rows from SampleCrsr. */
GO
CLOSE SampleCrsr
GO
DEALLOCATE SampleCrsr
GO
局部游标为存储过程和触发器中执行的游标提供了重要的保护作用。全局游标可以在声明它们的存储过程或触发器的外部被引用。因此,存储过程或触发器的外部语句可能会在无意中更改它们。因为不能在存储过程以外引用局部游标,因此局部游标比全局游标更安全,除非故意将局部游标作为游标输出参数返回调用方。
因为可以在存储过程或触发器的外部引用全局游标,所以全局游标可能会在无意中影响其它语句。例如,在存储过程中创建了一个名为 xyz 的全局游标,在存储过程结束时此游标是打开的。当此存储过程完成后若要使用 xyz 来声明另一个全局游标,则会因为使用重复的名称错误而导致失败。
全局游标和局部游标有各自的名称空间,因此可以同时有相同名称的全局游标和局部游标。接受游标命名参数的Transact-SQL 语句也支持 GLOBAL 关键字来标识名称的作用域。如果没有指定 GLOBAL,且在游标名称参数中同时有指定了此名称的全局游标和局部游标,则引用此局部游标。
如果 LOCAL和 GLOBAL 都没有指定,则数据库选项default to local cursor 控制由 DECLARE CURSOR 语句使用的默认值。如果 default to local cursor 为 true,Transact-SQL 游标默认为是局部的。如果此选项为 false,Transact-SQL 游标默认为是全局游标。在 SQL Server 2000版中,default to local cursors 选项默认为 FALSE,以便与 SQL Server 早期版本中的内容匹配。
使用 DECLARE 和 OPEN 局部游标的存储过程可以将游标传递出去以供要求调用的存储过程、触发器或批处理使用。这可以通过使用由新的 CURSOR VARYING 数据类型定义的 OUTPUT 参数来实现。游标变量只能用作 OUTPUT 参数。不能将它们用于输入参数。当存储过程完成时游标必须是打开的,以便将游标返回 OUTPUT 参数。也可以通过新的 CURSOR 数据类型来声明局部变量以包含对局部游标的引用。
USE pubs
GO
/* Create a procedure with a cursor output parameter. */
CREATE PROCEDURE OpenCrsr @OutCrsr CURSOR VARYING OUTPUT AS
SET @OutCrsr = CURSOR FOR
SELECT au_lname
FROM authors
WHERE au_lname LIKE 'S%'
OPEN @OutCrsr
GO
/* Allocate a cursor variable. */
DECLARE @CrsrVar CURSOR
/* Execute the procedure created earlier to fill
the variable. */
EXEC OpenCrsr @OutCrsr = @CrsrVar OUTPUT
/* Use the variable to fetch the rows from the cursor. */
FETCH NEXT FROM @CrsrVar
WHILE (@@FETCH_STATUS <> -1)
BEGIN
FETCH NEXT FROM @CrsrVar
END
CLOSE @CrsrVar
DEALLOCATE @CrsrVar
GO
数据库 API 不支持存储过程中的游标输出参数。不能直接从数据库 API 函数执行包含游标输出参数的存储过程。而只能从另一个存储过程、触发器、Transact-SQL 批处理或脚本执行这些存储过程。
只有在明确释放时或关闭连接时 GLOBAL 游标才可用。创建 LOCAL 游标的存储过程、触发器或批处理终止时将隐性释放 LOCAL 游标,除非游标已作为参数返回。当调用过程的代码中引用游标的参数或变量超出作用域时,将隐性地释放 LOCAL 游标。
转载
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述