2011-12-01 76 views
1

我正在开发使用SSMS 2008的TSQL存储过程,并在生成CTE时收到上述错误。我想为这个SP添加逻辑来每天返回,而不仅仅是数据的日子。我该怎么做呢?这里是我的SP至今:TSQL CTE错误:''''附近的语法不正确

ALTER Proc [dbo].[rpt_rd_CensusWithChart] 
    @program uniqueidentifier = NULL, 
    @office uniqueidentifier = NULL 
AS 
DECLARE @a_date datetime 
SET @a_date = case when MONTH(GETDATE()) >= 7 THEN '7/1/' + CAST(YEAR(GETDATE()) AS VARCHAR(30)) 
ELSE '7/1/' + CAST(YEAR(GETDATE())-1 AS VARCHAR(30)) END 

if exists (
    select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..#ENROLLEES') 
) DROP TABLE #ENROLLEES; 
if exists (
    select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..#DISCHARGES') 
) DROP TABLE #DISCHARGES; 

declare @sum_enrollment int 

set @sum_enrollment = 
(select sum(1) 
from enrollment_view A 
join enrollment_info_expanded_view C on A.enrollment_id = C.enroll_el_id 
where 
    (@office is NULL OR A.group_profile_id = @office) 

    AND (@program is NULL OR A.program_info_id = @program) 
and (C.pe_end_date IS NULL OR C.pe_end_date > @a_date) 
AND C.pe_start_date IS NOT NULL and C.pe_start_date < @a_date) 

select 
A.program_info_id as [Program code], 
A.[program_name], 
A.profile_name as Facility, 
A.group_profile_id as Facility_code, 
A.people_id, 
1 as enrollment_id, 

C.pe_start_date, 
C.pe_end_date, 
LEFT(datename(month,(C.pe_start_date)),3) as a_month, 
day(C.pe_start_date) as a_day, 
@sum_enrollment as sum_enrollment 

into #ENROLLEES 
from enrollment_view A 
join enrollment_info_expanded_view C on A.enrollment_id = C.enroll_el_id 
where 
    (@office is NULL OR A.group_profile_id = @office) 
    AND (@program is NULL OR A.program_info_id = @program) 
and (C.pe_end_date IS NULL OR C.pe_end_date > @a_date) 

AND C.pe_start_date IS NOT NULL and C.pe_start_date >= @a_date 

;WITH #ENROLLEES AS (
    SELECT '7/1/11' AS dt 
    UNION ALL 
    SELECT DATEADD(d, 1, pe_start_date) as dt 
     FROM #ENROLLEES s 
    WHERE DATEADD(d, 1, pe_start_date) <= '12/1/11') 
+1

您可以[编辑]你的帖子,你知道的。 – Will

回答

5

最明显的问题(也可能是导致错误消息也一个)是没有到最后的CTE应该属于实际的语句。我认为它应该是一个SELECT语句,它将把CTE的结果集与#ENROLLEES表中的数据结合起来。

这就是另一个问题出现的地方。

您会发现,除了一个名称以单个#开头的名称几乎不适用于任何不是本地临时表的东西(CTE实际上不是表)之外,您还可以选择用于CTE一个已经属于现有表的特定名称(更确切地说,与已经提到的#ENROLLEES临时表相关)以及您将要从中提取数据的名称。您绝对不应该为CTE使用现有的表名,否则由于名称冲突,您将无法将其与CTE结合使用。

它似乎也是基于它的代码,最后一个CTE表示您要添加到SP的逻辑的未完成实现。我可以提出一些想法,但在继续之前,我希望你能意识到在你的文章中实际上有两种不同的请求。一个是找出错误信息的原因,另一个是关于新逻辑的代码。一般来说,将这些请求分成不同的问题可能会更好,因此您可能也会遇到这种情况。

不管怎么说,这是我的建议:

  • 构建要在结果集进行会计处理(这是什么CTE将用于)日期的完整列表;

  • 将该列表与#ENROLLEES表左移,为现有日期选择数据,为不存在的列表选择一些默认值或NULL。

它可能会实现这样的:

… /* all your code up until the last WITH */ 
; 
WITH cte AS (
    SELECT CAST('7/1/11' AS date) AS dt 
    UNION ALL 
    SELECT DATEADD(d, 1, dt) as dt 
    FROM cte 
    WHERE dt < '12/1/11' 
) 
SELECT 
    cte.dt, 
    tmp.[Program code], 
    tmp.[program_name], 
    … /* other columns as necessary; you might also consider 
     enveloping some or all of the "tmp" columns in ISNULLs, 
     like in 

     ISNULL(tmp.[Program code], '(none)') AS [Program code] 

     to provide default values for absent data */ 
FROM cte 
    LEFT JOIN #ENROLLEES tmp ON cte.dt = tmp.pe_start_date 
; 
+0

#facepalm ...没有选择,因为我试图调试语法错误。我写了很多CTE,显然今天是我注意到红色波浪式大声笑的唯一一天 – afreeland

相关问题