Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope of an CTE in SQL Server 2005

Tags:

sql-server

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

This works fine

If the same query is written like 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

it gives a message telling emp_CTE does not exist.

Is there any way we can overcome this issue?

thanks Prince

like image 543
happysmile Avatar asked Jul 27 '11 06:07

happysmile


People also ask

What is the scope of CTE in SQL Server?

Specifies a temporary named result set, known as a common table expression (CTE). This is derived from a simple query and defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE or MERGE statement. This clause can also be used in a CREATE VIEW statement as part of its defining SELECT statement.

What is CTE scope of CTE and where CTE get stored?

According to the CTE documentation, Common Table Expression is a temporary result set or a table in which we can do CREATE, UPDATE, DELETE but only within that scope. That is, if we create the CTE in a Stored Procedure, we can't use it in another Stored Procedure.

What is the limitation of CTE in SQL Server?

A CTE can be referred for multiple times in a query. As the scope is limited to the batch, multiple CTEs can have the same name which a view cannot have.

What is the advantage of CTE in SQL Server?

Advantages of CTE CTE improves the code readability. CTE provides recursive programming. CTE makes code maintainability easier. Though it provides similar functionality as a view, it will not store the definition in metadata.


1 Answers

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;

like image 56
gbn Avatar answered Oct 26 '22 20:10

gbn