我有一个存储过程,现在我不是一个DBA,所以我只是想知道这是否被认为是不好的做法,因为我有很多子查询具有基本相同的代码。
我应该使用表变量还是临时表?
此外,我必须重新编写第二个查询作为动态SQL,因为我只想包含基于标志的联合,因此临时表在这里会更容易。
感谢您的帮助
CREATE TABLE #Days(theDate datetime, DayAsString varchar(15))
CREATE TABLE #temp(id int identity(1,1),trip_date datetime, trip_return datetime, iteration int, weeknumber int)
IF @SpecificDay = 0
Begin
INSERT INTO #Days
SELECT [date] ,DATENAME(dw,[date])
FROM dbo.Calendar C
WHERE [Date] BETWEEN @start AND @end
AND C.[WkDName] in (select distinct siDay.Name
from schedule s
join ScheduleItemIntervalMap sim on s.schedule_id = sim.scheduleid
join scheduleInterval sint on sim.scheduleIntervalID = sint.id
left join ScheduleItem siDay on sim.scheduleDayItemId = siDay.id
where s.schedule_id = @schedule_id
) --@wkDName
AND C.[Month] in (select distinct siMonth.Id
from schedule s
join ScheduleItemIntervalMap sim on s.schedule_id = sim.scheduleid
join scheduleInterval sint on sim.scheduleIntervalID = sint.id
join ScheduleItem siMonth on sim.ScheduleMonthItemId = siMonth.id
where s.schedule_id = @schedule_id
) --@Month
AND C.[WkNo] in (select distinct sint.Id
from schedule s
join ScheduleItemIntervalMap sim on s.schedule_id = sim.scheduleid
join scheduleInterval sint on sim.scheduleIntervalID = sint.id
join ScheduleItem siDay on sim.ScheduleDayItemId = siDay.Id
where s.schedule_id = @schedule_id) --@first last etc @occurence
Union all --include the last occurence of the month
SELECT [date] ,DATENAME(dw,[date])
FROM dbo.Calendar CLast
WHERE [Date] BETWEEN @start AND @end
AND CLast.[WkDName] in (select distinct siDay.Name
from schedule s
join ScheduleItemIntervalMap sim on s.schedule_id = sim.scheduleid
join scheduleInterval sint on sim.scheduleIntervalID = sint.id
left join ScheduleItem siDay on sim.scheduleDayItemId = siDay.id
where s.schedule_id = @schedule_id
) --@wkDName
AND CLast.[Month] in (select distinct siMonth.Id
from schedule s
join ScheduleItemIntervalMap sim on s.schedule_id = sim.scheduleid
join scheduleInterval sint on sim.scheduleIntervalID = sint.id
join ScheduleItem siMonth on sim.ScheduleMonthItemId = siMonth.id
where s.schedule_id = @schedule_id
) --@Month
AND CLast.[Last] = 1
END
ELSE --Specific date has been specified or last has been selected
INSERT INTO #Days
select distinct [date] ,DATENAME(dw,[date]) from
(
SELECT *
FROM dbo.Calendar C
WHERE [Date] BETWEEN @start AND @end
AND C.[Month] in (select distinct siMonth.Id
from schedule s
join ScheduleItemIntervalMap sim on s.schedule_id = sim.scheduleid
join scheduleInterval sint on sim.scheduleIntervalID = sint.id
join ScheduleItem siMonth on sim.ScheduleMonthItemId = siMonth.id
where s.schedule_id = @schedule_id) --@Month
AND C.[Day] in (select distinct sint.Name
from schedule s
join ScheduleItemIntervalMap sim on s.schedule_id = sim.scheduleid
join scheduleInterval sint on sim.scheduleIntervalID = sint.id
join ScheduleItem siMonth on sim.ScheduleMonthItemId = siMonth.id
where s.schedule_id = @schedule_id
AND sint.Name <> 'Last'
)
Union all --include the last occurence of the month IF LAST
SELECT *
FROM dbo.Calendar CLast
WHERE [Date] BETWEEN @start AND @end
AND CLast.[Month] in (select distinct siMonth.Id
from schedule s
join ScheduleItemIntervalMap sim on s.schedule_id = sim.scheduleid
join scheduleInterval sint on sim.scheduleIntervalID = sint.id
join ScheduleItem siMonth on sim.ScheduleMonthItemId = siMonth.id
where s.schedule_id = @schedule_id
) --@Month
AND [Date] in (select LDtOfMo from dbo.Calendar
WHERE [Date] BETWEEN @start AND @end)
) as x
Begin
INSERT INTO #temp(trip_date,trip_return,iteration,weeknumber)
SELECT
theDate + CAST(@timeout AS DATETIME),theDate+ CAST(@timeback AS DATETIME),@WeekNo,DATEPART(wk, theDate+CAST(@timeout AS DATETIME))
FROM
#Days
END
答案 0 :(得分:0)
因为你反复做同样的JOIN
;您可以转换JOIN
中的子查询,如下所示
INSERT INTO #Days
SELECT DISTINCT C.[date] ,DATENAME(dw,C.[date])
FROM dbo.Calendar C
left join ScheduleItem si
ON si.Name = C.[WkDName]
AND si.Id = C.[Month]
JOIN ScheduleItemIntervalMap sim ON sim.scheduleDayItemId = si.id
JOIN schedule s ON s.schedule_id = sim.scheduleid
JOIN scheduleInterval sint on sim.scheduleIntervalID = sint.id
AND sint.Id = C.[WkNo]
where s.schedule_id = @schedule_id
AND C.[Date] BETWEEN @start AND @end