我正在使用SSMS 2008开发TSQL存储过程,并在生成CTE时收到上述错误。我想为此SP添加逻辑以返回每天,而不仅仅是数据的日子。我该怎么做呢?到目前为止,这是我的SP:
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')
答案 0 :(得分: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
;