Вот проблема, с которой я столкнулся: у меня большой запрос, который должен сравнить дату и время в предложении where, чтобы увидеть, совпадают ли две даты в один и тот же день. Мое текущее решение, которое отстой, состоит в том, чтобы отправить datetime в UDF, чтобы преобразовать их в полночь того же дня, а затем проверить эти даты на равенство. Когда дело доходит до плана запроса, это катастрофа, как и почти все пользовательские функции в соединениях или предложениях where. Это одно из немногих мест в моем приложении, где мне не удалось отключить функции и дать оптимизатору запросов что-то, что он может использовать для определения наилучшего индекса.
В этом случае объединение кода функции обратно в запрос представляется нецелесообразным.
Я думаю, что мне здесь не хватает чего-то простого.
Вот функция для справки.
if not exists (select * from dbo.sysobjects
where id = object_id(N'dbo.f_MakeDate') and
type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
exec('create function dbo.f_MakeDate() returns int as
begin declare @retval int return @retval end')
go
alter function dbo.f_MakeDate
(
@Day datetime,
@Hour int,
@Minute int
)
returns datetime
as
/*
Creates a datetime using the year-month-day portion of @Day, and the
@Hour and @Minute provided
*/
begin
declare @retval datetime
set @retval = cast(
cast(datepart(m, @Day) as varchar(2)) +
'/' +
cast(datepart(d, @Day) as varchar(2)) +
'/' +
cast(datepart(yyyy, @Day) as varchar(4)) +
' ' +
cast(@Hour as varchar(2)) +
':' +
cast(@Minute as varchar(2)) as datetime)
return @retval
end
go
Чтобы усложнить ситуацию, я присоединяюсь к таблицам часовых поясов, чтобы сравнить дату с местным временем, которое может быть различным для каждой строки:
where
dbo.f_MakeDate(dateadd(hh, tz.Offset +
case when ds.LocalTimeZone is not null
then 1 else 0 end, t.TheDateINeedToCheck), 0, 0) = @activityDateMidnight
[Изменить]
Я включил предложение @ Тодда:
where datediff(day, dateadd(hh, tz.Offset +
case when ds.LocalTimeZone is not null
then 1 else 0 end, t.TheDateINeedToCheck), @ActivityDate) = 0
Мое неправильное представление о том, как работает datediff (тот же день года в последовательных годах дает 366, а не 0, как я ожидал), заставило меня напрасно тратить много усилий.
Но план запроса не изменился. Я думаю, что мне нужно вернуться к чертежной доске со всем этим.