SQL中declare变量的作用域(续)一些问题

摘要:
在上次讨论了声明变量的范围之后,让我们继续深入讨论它。确切地说,我有一些疑问,想和你讨论一下。如果你知道什么,请给我一些建议。请注意,代码使用Northwind数据库。如果您需要Northwind数据库,请访问http://msdn.microsoft.com/zh-cn/library/ms143221.aspxDECLARE @ idINTDECLAREmyCURSORCURSORFORSELECTTOP3c.CategoryIDFROMCategoriescOPENmyCURSORFETCHNEXTFROMmyCURSORINTO@idWHILE@@FETCH_ STATUS=0BEGIN——电流回路的ID输出SELECT@idDECLARE @ TessTableTABLE--DELETEFROM@TessTableINSERTINTO@TessTableSELECTp。产品名称FROMProductspWHERE。CategoryID=@id--输出当前循环id下所有产品名称的SELECT*FROM@TessTableFETCHNEXTFROMmyCURSORINTO@idENDCLOSEMMyCURSORDEALLOCATEMMYCURSOREND的逻辑相对简单。它是从分类表中获取所有分类ID,通过光标循环所有ID,并依次在表变量中显示每个类别的商品名称。这个查询没有实际意义,只是为了说明问题。它对代码本身要求不高。

在上次讨论了declare变量的作用域以后我们继续深入谈论一下,准确的说是我有些疑惑想跟大家讨论,有高手明白的话指点一下。

关于作用域的谈论:http://www.cnblogs.com/breezeli/archive/2010/04/16/1713308.html

这个问题不太好解释,大家看一段代码,在循环中定义表变量。

注意代码使用Northwind数据库,需要Northwind库的请访问http://msdn.microsoft.com/zh-cn/library/ms143221.aspx

 

DECLARE @id INT
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

注意

表结构是我随意捏造的跟Northwind略有不同

这样的数据那我认为的输出的两个表,以第1次循环来应该是

无名列

1

1

Name

1

Chai

2

Chang

实际截图:

  

SQL中declare变量的作用域(续)一些问题第1张

第二次循环的第一个输出表的内容就应该是2,二个输出表应该就一项应该是Aniseed Syrup,不知道多少人跟我想的一样,可惜的是有多少人跟我想的一样就有多少人错了。

实际的结果第二次循环的输出内容为:

无名列

1

2

 

Name

1

Chai

2

Chang

3

Aniseed Syrup

第二次的查询结果是追加在第一次查询结果的表变量里的,为什么这样,我只能猜测,第一次循环时定义了表变量,因为declare的作用域是整个批处理,所以第二次循环是declare语句就不在执行了,当然这没什么理论依据,只是根据查询推断出来的,按说定义了一个变量再一次定义同名变量,应该会有错误,但是以上代码可以完好只执行,放到try里面也捕捉不到错误,哪位大虾能说清具体原理的指教一下小弟。

如果你想得到正确的结果那就把declare下面那句delete打开,每次都清一下数据结果就是正确的了。

 

说完表变量,那大家想象如果是变量做这样的操作,会不会累加啊?我上代码:

 

    DECLARE @i INT
    
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:1

i:2

i:3

i:4

i:5

 

这就是结果,根本没有print @t的内容,而且同样放到try里面不报错

这句--set @t='0'打开给@t赋一个初始值的话下面就就可以输出了但是结果依然很神奇

i:1

t:a

i:2

t:a

i:3

t:a

i:4

t:a

i:5

t:a

 

谁能告诉我为什么?

免责声明:文章转载自《SQL中declare变量的作用域(续)一些问题》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Hibernate-入门教程经典的JAVA面试题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

R语言ggmap空间可视化机动车交通事故地图

原文链接:http://tecdat.cn/?p=12350 在本文中,我使用ggmap可视化纽约市的交通事故。  数据来自纽约市开放数据。我的数据范围是2012年至2015年。该数据跟踪车辆的类型,发生事故的街道的名称以及事故的经度和纬度坐标。两个坐标都保存为单个字符变量,称为“ LOCATION”。 在下面,我加载数据,删除所有没有位置坐标的事故,并...

postman集合(变量及集合执行)

1.变量 1)按照作用域分为全局变量,环境变量,本地变量,数据变量(覆盖顺序为反方向) ->在集合运行器中,数据变量覆盖其他变量 2)变量使用 一般使用 在body中使用,需要预先设置     执行之后,可以查看当次变量值  3)数据文件 在可以使用环境变量的地方都可以使用数据文件,除了pre-requestScript,test 使用数据文件...

Clion Debug模式使用实践

一、背景 最近为了考研,在学习C语言与数据结构,最开始使用Visual Studio 2019作为编辑器,但是总感觉不习惯; 之前一直使用jetbrains公司的编辑器,正好发现C语言可以用CLion,但是发现不会使用他的调试功能,有些时候为了调试代码,还需要将代码复制到 Visual Studio 2019编辑器中;后来觉得太麻烦了,摸索了一段时间终于找...

在ORACLE中存储过程变量名和表字段名相同

1.事件概述 今天再写存储过程使用变量没注意到问题,导致SQL执行缓慢,找了许久才发现哪里有问题。 2.发现问题 在存储过程中执行下图sql需要20秒左右,执行计划发现走了全表扫描,而在存储过程中相同的SQL不会有问题。 然后我单独把SQL拿出来跑,将变量名替换成真实数据,1秒就执行出来了,执行计划走了索引。 存储过程重新看了很久,是不是哪里有问题,变量...

Effective_go 阅读笔记

目录 Commentary(注释) Naming conventions(命名规则) 包名 接收者 接口名称 混合名称 Semicolons(分号) Control structures(控制语句) if for switch type switch 函数 多返回值 可命名结果形参 defer Data new 分配 构造函数和混合...

五. python数据转换

1. 数据转换    set  tuple   list  dict  int   float # list ----set a1=[1,2,3,4,5,6] a2=set(a1) print(a2) #{1, 2, 3, 4, 5, 6} # tuple----set a3=(1,2,3000,4,5,600000) a4=set(a3) pr...