Я думаю, что этот T-SQL эквивалентен вашему коду:
-- set time portion of @DateStart back to midnight
SET @DateStart = CONVERT(DATETIME,CONVERT(VARCHAR(10),@DateStart,20),20)
-- advance time portion of @DateEnd to last instant before next midnight
SET @DateEnd = CONVERT(DATETIME,CONVERT(VARCHAR(11),@DateEnd,20)+'23:59:59.997',21)
Функция CONVERT
будет обрабатывать NULLS, поэтому нет необходимости в отдельном тесте для значения NULL (если, конечно, вы не выполняете какую-то специальную обработку, отличную от того, что вы показываете, и не передаете значения NULL предикат запроса (т. е. предложение WHERE). Или, возможно, вы ожидаете, что многие аргументы будут равны NULL, и вы хотите избежать издержек при вызовах CONVERT.
Однако я согласен с рекомендацией Тома Х. и не путаюсь с вычитанием миллисекунд, а вместо этого устанавливаю @DateEnd в полночь следующего дня, например
-- advance @DateEnd to midnight of following day
SET @DateEnd = DATEADD(day,1,CONVERT(DATETIME,CONVERT(VARCHAR(10),@DateEnd,20),20))
и измените предикат, чтобы выполнить тест диапазона следующим образом:
WHERE (EventDate >= @DateStart AND EventDate < @DateEnd)
Вы можете избежать отдельных операторов SET и переместить выражения прямо в запрос, но я не ожидаю, что это повысит производительность и затруднит чтение оператора SQL, вы определенно захотите оставить комментарии ...
WHERE (EventDate> = CONVERT (DATETIME, CONVERT (VARCHAR (10), @ DateStart, 20), 20)
И EventDate