SQL中declare变量的作用域(续)-----一些问题
在上次讨论了declare变量的作用域以后我们继续深入谈论一下,准确的说是我有些疑惑想跟大家讨论,有高手明白的话指点一下。
关于作用域的谈论:http://www.cnblogs.com/breezeli/archive/2010/04/16/1713308.html
这个问题不太好解释,大家看一段代码,在循环中定义表变量。
DECLARE myCURSOR CURSOR FOR
SELECT TOP 3 c.CategoryID FROM Categories c
OPEN myCURSOR
FETCH NEXT FROM myCURSOR INTO @id
WHILE @@FETCH_STATUS = 0
BEGIN
--当前循环的id输出
SELECT @id
DECLARE @TessTable TABLE (
[name] NVARCHAR(40)
)
--DELETE FROM @TessTable
INSERT INTO @TessTable
SELECT p.ProductName
FROM Products p
WHERE p.CategoryID=@id
--当前循环的id下所有的产品名称输出
SELECT * FROM @TessTable
FETCH NEXT FROM myCURSOR INTO @id
END
CLOSE myCURSOR
DEALLOCATE myCURSOR
END
逻辑比较简单,就是从分类表(Categories)中取出所有分类的id,游标循环所有id,依次把每个类别的商品名称放到表变量中显示出来,这个查询没有实际意义就是为了展示一下问题,对代码本身的优劣不做过多要求。
不知道大家看了这个查询后想象到的输出结果应该是什么样的?我认为结果是每次循环输出两个表,第一个是SELECT @id的结果输出当前循环到的CategoryID ,另一个是SELECT * FROM @TessTable的结果输出属于@id的所有产品的名称
举例来说:
比如我们现在有数据:
Categories表
CategoryID |
Name |
1 |
Beverages |
2 |
Condiments |
Products
Id |
ProductName |
CategoryID |
1 |
Chai |
1 |
2 |
Chang |
1 |
3 |
Aniseed Syrup |
2 |
这样的数据那我认为的输出的两个表,以第1次循环来应该是
|
无名列 |
1 |
1 |
|
Name |
1 |
Chai |
2 |
Chang |
实际截图:
第二次循环的第一个输出表的内容就应该是2,二个输出表应该就一项应该是Aniseed Syrup,不知道多少人跟我想的一样,可惜的是有多少人跟我想的一样就有多少人错了。
实际的结果第二次循环的输出内容为:
|
无名列 |
1 |
2 |
|
Name |
1 |
Chai |
2 |
Chang |
3 |
Aniseed Syrup |
第二次的查询结果是追加在第一次查询结果的表变量里的,为什么这样,我只能猜测,第一次循环时定义了表变量,因为declare的作用域是整个批处理,所以第二次循环是declare语句就不在执行了,当然这没什么理论依据,只是根据查询推断出来的,按说定义了一个变量再一次定义同名变量,应该会有错误,但是以上代码可以完好只执行,放到try里面也捕捉不到错误,哪位大虾能说清具体原理的指教一下小弟。
如果你想得到正确的结果那就把declare下面那句delete打开,每次都清一下数据结果就是正确的了。
说完表变量,那大家想象如果是变量做这样的操作,会不会累加啊?我上代码:
SET @i=1
WHILE @i<6
BEGIN
PRINT 'i:'+cast(@i AS nVARCHAR)
DECLARE @t VARCHAR
-- set @t='0'
SET @t='a'+@t+cast(@i AS nVARCHAR)
PRINT 't:'+cast(@t AS nVARCHAR)
SET @i=@i+1
END
GO
猜谜继续啊,你们猜猜是什么结果。
我直接说好了
i:2
i:3
i:4
i:5
这就是结果,根本没有print @t的内容,而且同样放到try里面不报错
这句--set @t='0'打开给@t赋一个初始值的话下面就就可以输出了但是结果依然很神奇
t:a
i:2
t:a
i:3
t:a
i:4
t:a
i:5
t:a
谁能告诉我为什么?
【推荐】国内首个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 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述