【问题标题】:Scope of an CTE in SQL Server 2005SQL Server 2005 中 CTE 的范围
【发布时间】:2011-07-27 06:21:15
【问题描述】:
WITH emp_CTE AS (
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS IdentityId, *
    FROM dbo.employee )
SELECT * FROM emp_CTE

这很好用

如果同样的查询是这样写的。

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

它给出一条消息,告诉emp_CTE 不存在。

有什么办法可以解决这个问题吗?

谢谢 王子

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    CTE 只是后续语句的一部分。

    后续语句可以是单个 SELECT/INSERT/UPDATE/DELETE,或复合(与 UNION、INTERSECT 等)

    例如:

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

    经验法则是范围是直到下一个; 的位置。分号终止任何语句,但不幸的是它是可选的。

    您上面的失败代码实际上是这样的

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

    所以 CTE 仅在 ...EMPLOYEES; 之前的范围内

    【讨论】:

    • Stack Overflow 的神奇之处在于,我可以在当地时间将近下午 1030 点坐在这里,喝着啤酒,想知道为什么我的代码不工作,然后在几秒钟内找到我需要的东西。跨度>
    【解决方案2】:

    简而言之:不。 CTE 对单个 next 语句完全有效 - 仅此而已。而且也没有办法“延长” CTE 的寿命。

    来自MSDN Books Online

    公用表表达式 (CTE) 可以被认为是临时的 在单个的执行范围内定义的结果集 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句。 CTE 是 类似于派生表,因为它不存储为对象和 仅在查询期间持续

    你可以:

    • 将您的 CTE 转换为视图并将该视图用于您的查询 - 只要定义了视图,它们就可用

    • 将 CTE 的结果存储到临时表或表变量中以供进一步处理

    • 在 CTE 之后更改您的语句,以便它们可以作为单个语句执行

      WITH emp_CTE AS (
      ......)
      SELECT (list of columns)
      FROM emp_CTE
      INNER JOIN dbo.Employees e ON ......
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多