zoukankan      html  css  js  c++  java
  • SQL中declare变量的作用域(续)一些问题

    在上次讨论了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

    实际截图:

      

    第二次循环的第一个输出表的内容就应该是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

     

    谁能告诉我为什么?

  • 相关阅读:
    Javascript进阶(7)---函数参数
    Django连接mssql(SqlServer)
    ORM查询
    Django-Model操作数据库
    Django去操作已经存在的数据库
    如何设置CentOS 7获取动态及静态IP地址
    nginx代理设置
    Django+Linux+Uwsgi+Nginx项目部署文档
    nginx的安装部署
    Django项目在linux系统中虚拟环境部署
  • 原文地址:https://www.cnblogs.com/breezeli/p/1713570.html
Copyright © 2011-2022 走看看