#sql #sql-server
#sql #sql-сервер
Вопрос:
Я изменяю процедуру хранения в SQL Server 2008. Исходная процедура заняла две даты
@StartDate DATETIME
@EndDate DATETIME
И преобразовал бы временную часть в самое раннее и самое позднее возможное время соответственно.
Я добавил два дополнительных параметра для приема временных интервалов.
@StartTime DATETIME
@EndTime DATETIME
Временные интервалы необязательны.
Файл отчета RDL генерирует отчет онлайн для пользователей. Логика должна выполняться в сохраненной процедуре.
То, что у меня пока есть, не так много, поскольку я программист на C #, оставляющий свой элемент.
IF (@StartTime IS NULL)
SET @StartDate = fn_SetBeginningTime(@StartDate) -- Sets time portion to earliest value
ELSE
-- This is where I don't know how to add the time from @StartTime to the time portion of the datetime value @StartDate
IF (@EndTime IS NULL)
-- This will do the same as the start time/start date
Комментарии:
1. Если вы используете 2008, почему вы не используете более подходящие типы данных для этих параметров (например,
date
иtime
). Они упростили бы написание ответа, не требуя дополнительных предположений2. Как уже говорилось, я программист на C #, это мой первый опыт программирования на SQL. Я предполагаю, что DATETIME используется для @StartDate / @EndDate, поскольку к ним добавляется временная часть, а поля, которые они представляют, являются полями DateTime.
3. Сделайте шаг назад и расскажите нам, что вы делаете с временной частью даты. В SQL Server временная часть datetime по умолчанию равна полуночи, если вы не укажете время. Например,
Set @StarDate = '5/9/2011'
означает, что временная часть переменной будет равна полуночи.4. в TSQL
datetime
тип данных хранит дату и время. Некоторые люди имитируют дату только путем установки временной части на00:00:00.000
, но время все равно всегда есть. ИТАК, фактически ваша исходная процедура уже принимает два параметра date time.5. Просто для пояснения, я подумал, что разумно заполнить информацию на случай, если другие придут искать и найдут этот пост. Исходная сохраненная процедура использовала два параметра date time, @StartDate, @StartEnd. Существуют функции для ввода значений времени этих DateTimes в 00:00: 01 и 23:59:59 соответственно, чтобы включить все записи, которые совпали с этими датами или между ними. Я отвечаю за добавление временных фильтров, чтобы пользователи могли выбирать или не выбирать конкретные временные рамки для поиска. Отсюда использование операторов if IF для проверки, были ли значения времени добавлены пользователем или нет.
Ответ №1:
Предполагая:
- Под самым ранним вы подразумеваете 00:00:00 в начальную дату
- Под последней вы подразумеваете 00:00:00 на следующий день после enddate (для использования с
<=
)
Если таковые имеются, это проигнорирует время из @*Date
параметра и дату из @*Time
параметра.
declare @StartDate DATETIME = '15 jul 2010'
declare @EndDate DATETIME = '15 jul 2010'
declare @StartTime DATETIME = '06:06:06'
declare @EndTime DATETIME = null
--always make @StartDate/@EndDate's time 00:00:00
SET @StartDate = CAST(@StartDate AS DATE)
SET @EndDate = CAST(@EndDate AS DATE)
IF (@StartTime IS NOT NULL) -- set @StartDate's time to @StartTime
SET @StartDate = CAST(@StartTime AS TIME)
IF (@EndTime IS NULL)
SET @EndDate = 1 --set it to midnight
ELSE
SET @EndDate = CAST(@EndTime AS TIME) --set @EndDate's time to @EndTime
select @StartDate, @EndDate
>>> 2010-07-15 06:06:06.000,2010-07-16 00:00:00.000
Для ДАТЫ / ВРЕМЕНИ;
declare @StartDate DATE = '15 jul 2010'
declare @EndDate DATE = '15 jul 2010'
declare @StartTime TIME = null
declare @EndTime TIME = '22:22:22'
declare @start datetime = cast(@StartDate as datetime) coalesce(@StartTime, cast('00:00:00' as time))
declare @end datetime = cast(@EndDate as datetime) coalesce(@EndTime, cast('23:59:59' as time))
select @start, @end
Комментарии:
1. Ваши предположения соответствуют цели. Функции fn_SetTimes установят время начала в полночь, а время окончания в 23:59:59 для использования с <= .
2. Я думаю, это приводит меня к другому вопросу. Поскольку я могу изменить тип параметра @startTime и @EndTime. Было бы лучше объявить их как значения ВРЕМЕНИ? Таким образом, ЕСЛИ (@startTime НЕ РАВНО NULL) УСТАНОВИТЬ @StartDate = @startTime или ПРИВЕДЕНИЕ будет необходимо в любом случае, поскольку мы добавляем временную часть к значению DATETIME?
3. Часть моей реальной дилеммы заключается в отсутствии тестовой среды. Таким образом, любые изменения, которые я вношу, поступают на рабочий сервер в режиме реального времени. Глупо, я знаю, но я не устанавливаю здесь правила.
4. Да, я создал новую копию сохраненной процедуры и использую ее для внесения своих изменений, а не просто модифицирую существующую.
5. Вы могли бы использовать параметры DATE / TIME, но вам понадобились бы 2 новые переменные для хранения окончательной ДАТЫ ВРЕМЕНИ, и вам также нужно было бы использовать DATEADD(), поскольку DATE int недопустимо, как и для date time