2011-12-01 74 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

相關問題