初学者:在while循环外使用“With”?

时间:2011-12-08 11:14:06

标签: tsql while-loop

我是一个初学者问题。

这是一段有效的代码:

declare @RowNr int = 1
declare @CA int = 0

While @RowNr <= 1000
BEGIN
    With CCWithRow AS
    (
        SELECT CA ,ROW_NUMBER() OVER (order by CA) as RowNr
        FROM myCATable
    )

    SELECT @CA = CA, @RowNr = RowNr
    FROM CCWithRow
    WHERE RowNr = @RowNr
    Set @RowNr +=  1

--Doing something with @CA here
END

此代码不会:

    declare @RowNr int = 1
    declare @CA int = 0

    With CCWithRow AS
    (
            SELECT CA ,ROW_NUMBER() OVER (order by CA) as RowNr
        FROM myCATable
    )

    While @RowNr <= 1000
    BEGIN
        SELECT @CA = CA, @RowNr = RowNr
        FROM CCWithRow
        WHERE RowNr = @RowNr
        Set @RowNr +=  1    
--Doing something with @CA here
    END

问题:为什么我必须在循环内“定义”WITH?

我知道有更好的方法来解决原始问题,因此不应该成为主题。只是想知道,为什么我不能在循环之外定义WITH并在里面使用它。

3 个答案:

答案 0 :(得分:2)

From BOL

  

公用表表达式(CTE)可以被认为是临时表   在单个的执行范围内定义的结果集   SELECT,INSERT,UPDATE,DELETE或CREATE VIEW语句。

因此,公共表表达式用法必须在CTE定义结束后立即始终,因为它不在其他任何地方引用的范围内。这种情况也不例外。

答案 1 :(得分:1)

这是CTE的实施:

  

CTE只能由语句立即引用   遵循CTE 。这意味着如果你想使用CTE,你必须这样做   在CTE之后立即写入引用CTE的查询   T-SQL批处理。 (ref

CTE的结果不是创建的对象,它只是一组基于CTE表达式解析的结果,非常类似于(select ..)子查询,类似于您无法在其他地方访问。

答案 2 :(得分:1)

检查MSDN Common Table Expressions

上的以下声明

可以将公用表表达式(CTE)视为已定义的临时结果集within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement.

  

它不会作为对象存储,只会持续一段时间   查询。在前面的select语句之后立即释放它   到CTE表达。

查看Microsoft Magazine文章的部分 - Structure of a CTE,了解有关CTE的更多信息。

  

CTE是一种语言级构造 - 意味着SQL Server没有   在内部创建临时或虚拟表。 CTE的基础查询   每次在紧接着的时候引用它时都会被调用   查询。