简体   繁体   English

使用CTE的SQL Server 2008动态查询

[英]SQL Server 2008 Dynamic Query using CTE

I am trying to write a Dynamic Query which uses a CTE. 我正在尝试编写一个使用CTE的动态查询。 But I am facing problems - see below This is a simplified case 但是我遇到了问题 - 见下文这是一个简化的案例

declare @DynSql varchar(max)='';
declare @cnt as integer;
with months as (
select CAST('07/01/2010' as DATE) stdt
UNION ALL
SELECT DATEADD(MONTH,1,STDT) FROM months
WHERE DATEADD(MONTH,1,STDT)<CAST('06/30/2011' AS DATE)
)
select COUNT(*) from months
set @DynSql='select * from months'
exec (@DynSql)

This does not work - the error I get is Invalid Object name 'Months' 这不起作用 - 我得到的错误是无效的对象名称'月'

Is there any way of achieving what I want. 有没有办法达到我想要的。 Will it work if I use Temp table or table variable. 如果我使用Temp表或表变量,它会工作吗

The with keyword does not declare an object that can be referenced in later queries. with关键字不声明可在以后的查询中引用的对象。 It is part of the select query. 它是选择查询的一部分。 Your dynamic sql was trying to reference an object months that did not exist. 您的动态SQL试图引用一个对象months不存在的。 Include the CTE in the string defining the dyanic query. 在定义dyanic查询的字符串中包含CTE。

declare @DynSql varchar(max)=''; 
set @DynSql=
'with months as ( 
    select CAST(''07/01/2010'' as DATE) stdt 
    UNION ALL 
    SELECT DATEADD(MONTH,1,STDT) FROM months 
    WHERE DATEADD(MONTH,1,STDT)<CAST(''06/30/2011'' AS DATE)) 
select * from months'
exec (@DynSql) 

However, I don't see what you gain by making the SQL dynamic, since nothing within the SQL statement varies. 但是,我没有看到通过使SQL动态获得什么,因为SQL语句中的任何内容都不同。


If you want an object you can reference later, you could create a view (once) that would be used by your dynamic query, and similar queries (many times). 如果您想要稍后可以引用的对象,则可以创建一个将由动态查询和类似查询(多次)使用的视图(一次)。

create view months_v as 
    with months as (select CAST('07/01/2010' as DATE) stdt 
        UNION ALL 
        SELECT DATEADD(MONTH,1,STDT) FROM months 
        WHERE DATEADD(MONTH,1,STDT)<CAST('06/30/2011' AS DATE)) 
    select * from months;
go

declare @DynSql varchar(max)='';
set @DynSql='select * from months_v' 
exec (@DynSql) 

Your dynamic SQL cannot reference months . 您的动态SQL无法引用months The scope of a CTE is a single statement : CTE的范围是单一声明

with cte as (cte definiton) select from cte;

If you want to re-use the CTE's result or definition, you have to either re-define the CTE every time you want to use it (eg. in the @DynSql) or materialize it's result into a table @variable and re-use the table @variable. 如果要重新使用CTE的结果或定义,则必须在每次要使用它时重新定义CTE(例如在@DynSql中)或将其结果实现到表@variable并重新使用表@variable。

Well I got it to work, but I do not understand the scope of this... 好吧,我让它工作,但我不明白这个范围...

declare @DynSql varchar(max)
declare @cnt as integer;
declare @stdt datetime;
Set @DynSql =''
Select @stdt = CAST('07/01/2010' as DATEtime);
with months as ( 
SELECT DATEADD(MONTH,1,@stdt) As [month] WHERE DATEADD(MONTH,1,@stdt)<CAST('06/30/2011' AS DATEtime) 
) 
select COUNT(*) from months 

Revision now that I have move information: 现在修改我有移动信息:

declare @DynSql varchar(max)
declare @cnt as integer;
declare @stdt datetime;
Set @DynSql = 'With ctemonths  as ('
Select @stdt = CAST('07/01/2010' as DATEtime);
Set @cnt = 1;
while @cnt <= 11 --(Select DateDiff(mm, @stdt, '06/30/2011'))
Begin
    IF (@CNT =1)
        Set @DynSql = @DynSql + 'Select DATEADD(MONTH,' + Cast(@cnt as nvarchar(2)) + ',''' + Convert(varchar(10), @stdt, 103) + ''') As [month] '
    eLSE
        Set @DynSql = @DynSql + 'UNION Select DATEADD(MONTH,' + Cast(@cnt as nvarchar

(2)) + ',''' + Convert(varchar(10), @stdt, 103) + ''') As [month] '
Set @cnt = @cnt + 1

End;

Set @DynSql = @DynSql + ') Select * from ctemonths' -- PIVOT (max([month]) for [month] in ([month]))'

exec (@DynSql)

You can't use that CTE or @TableVariable in a dynamic sql, but you can use a #Temp table for this. 您不能在动态sql中使用该CTE或@TableVariable,但您可以使用#Temp表。 Create a temp table, store the data in that ( u can copy your CTE result to temp table) and use it in dynamic query. 创建临时表,将数据存储在其中(您可以将CTE结果复制到临时表)并在动态查询中使用它。 That is the solution. 这是解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM