SQL Server 2005中CTE的范围

hap*_*ile 10 sql-server

WITH emp_CTE AS (
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS IdentityId, *
    FROM dbo.employee )
SELECT * FROM emp_CTE
Run Code Online (Sandbox Code Playgroud)

这很好用

如果相同的查询是这样写的.

WITH emp_CTE AS (
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS IdentityId, *
    FROM dbo.employee )
SELECT * FROM EMPLOYEES    
SELECT * FROM emp_CTE
Run Code Online (Sandbox Code Playgroud)

它给出了一条消息告诉emp_CTE不存在.

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

谢谢王子

gbn*_*gbn 13

CTE仅是后续声明的一部分.

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

例如:

;WITH cte1 AS
(
   select ...
), cte2 AS
(
    select ...
)
SELECT ...
UNION 
SELECT ...;
Run Code Online (Sandbox Code Playgroud)

经验法则是范围直到下一个范围;.分号终止任何语句,但遗憾的是它是可选的.

你上面的失败代码实际上就是这个

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

所以CTE只是在范围之前 ...EMPLOYEES;

  • Stack Overflow的奇迹是我可以在当地时间近1030 pm坐在这里,喝啤酒,想知道为什么我的代码无法正常工作,然后在几秒钟内找到我真正需要的东西。 (2认同)

mar*_*c_s 11

简而言之:不.CTE完全适用于单个,下一个语句 - 不再有.而且也没有办法"延长"CTE的寿命.

来自MSDN联机丛书:

公用表表达式(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 ......
    
    Run Code Online (Sandbox Code Playgroud)