Scope of an CTE in SQL Server 2005

后端 未结 2 1727
滥情空心
滥情空心 2020-12-06 18:01
WITH emp_CTE AS (
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS IdentityId, *
    FROM dbo.employee )
SELECT * FROM emp_CTE

This works fine<

相关标签:
2条回答
  • 2020-12-06 18:18

    The CTE is part of the subsequent statement only.

    The subsequent statement can be a single SELECT/INSERT/UPDATE/DELETE, or a compound (with UNION, INTERSECT etc)

    For example:

    ;WITH cte1 AS
    (
       select ...
    ), cte2 AS
    (
        select ...
    )
    SELECT ...
    UNION 
    SELECT ...;
    

    The rule of thumb is that the scope is until where next ; would be. A semi-colon terminates any statement but is optional unfortunately.

    Your failing code above is actually this

    ...;
    WITH emp_CTE AS (
        SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS IdentityId, *
        FROM dbo.employee )
    SELECT * FROM EMPLOYEES; 
    SELECT * FROM emp_CTE;
    

    So the CTE is only in scope up until ...EMPLOYEES;

    0 讨论(0)
  • 2020-12-06 18:35

    In short: NO. A CTE is valid exactly for the single, next statement - no more. And there's no way to "extend" the life of a CTE either.

    From MSDN Books Online:

    A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement. A CTE is similar to a derived table in that it is not stored as an object and lasts only for the duration of the query.

    You can:

    • turn your CTE into a view and use that view for your queries - views are available as long as they are defined

    • store the results of the CTE into a temporary table or table variable for further processing

    • change your statements after the CTE so they can be executed as a single statement

      WITH emp_CTE AS (
      ......)
      SELECT (list of columns)
      FROM emp_CTE
      INNER JOIN dbo.Employees e ON ......
      
    0 讨论(0)
提交回复
热议问题