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

     

    谁能告诉我为什么?

  • 相关阅读:
    PyQt作品 – PingTester – 多点Ping测试工具
    关于和技术人员交流的一二三
    Pyjamas Python Javascript Compiler, Desktop Widget Set and RIA Web Framework
    Hybrid Qt applications with PySide and Django
    pyjamas build AJAX apps in Python (like Google did for Java)
    PyQt 维基百科,自由的百科全书
    InfoQ:请问为什么仍要选择Java来处理后端的工作?
    Eric+PyQt打造完美的Python集成开发环境
    python select module select method introduce
    GUI Programming with Python: QT Edition
  • 原文地址:https://www.cnblogs.com/breezeli/p/1713570.html
Copyright © 2011-2022 走看看