2009-02-11 2 views
2

Я написал хранимую процедуру, которая принимает параметр даты. Меня беспокоит то, что между форматами дат American и British. Каков наилучший способ гарантировать отсутствие двусмысленности между датами, такими как 02/12/2008. Одна из возможностей заключается в том, чтобы пользователи вводили дату в формате, таком как 20081202 (yyyymmdd). Есть ли способ проверить это, не используя подстроки? В качестве альтернативы даты могут быть введены как 02-Dec-2008(dd-mmm-yyyy), но повторная проверка не является тривиальной, и есть потенциальные проблемы с пользователями, которые не используют английский.Проверка даты Дата Параметр в хранимой процедуре SQL Server

В дополнение к первым трем ответам. , , Одна из проблем заключается в том, что я ожидаю, что этот хранимый процесс будет вызываться напрямую без переднего конца, поэтому проверка полномочий proc не является вариантом. Это хорошая идея взять день, месяц и год в качестве отдельных параметров?

ответ

1

В результате я получил строковый параметр для даты и требую, чтобы пользователи вводили месяц как слово. Я проверяю, что ввод является допустимой датой, преобразуя его на дату. Чтобы обеспечить ввод месяца в качестве слова, я использую аналогичный компаратор для сравнения входной строки с «% Jan%» или «% Feb%» или «% Mar%» и т. Д.

4

У вас не будет никаких проблем, если вы хотите использовать параметры в вашем sproc:

create proc dbo.Sproc 
    @date datetime 
as 
    ... 
+0

Мы уже используем дату и время тип этой проблемы заключается в том, что в зависимости от настройки локализации пользователя одинаковые действительные входы времени и времени могут иметь разные значения. – macleojw

+0

Итак, вопрос не в том, что касается SQL, не так ли? Вы должны просто правильно разобрать ввод в своем слое презентации и передать серверу SQL действительное время. –

+0

У этого proc не будет слоя презентации. Вот почему это проблема SQL. – macleojw

4

Если объявить параметр как тип DATETIME или один из других типов набраны даты/времени в SQL Server, который вам нужно, то нет никакой двусмысленности; он представляет конкретную дату и время. Тип проверки, о котором вы говорите, должен происходить вне хранимой процедуры, а не внутри.

ОК с комментариями и изменениями, похоже, проблема связана с тем, как люди называют СП, а не фактически внутри него. Для этого вам просто нужно обучить пользователей использовать Сортируемый формат даты, т.е.

yyyy-MM-dd HH:mm:ss 

И тогда нет никакой двусмысленности. Любой, кто разрешен около, база данных должна знать о проблемах локализации и всегда должна использовать недискриминационный формат, подобный этому при вводе дат.

+0

Существует двусмысленность, поскольку значение даты зависит от настроек локализации. Например. 02/12/2008 - 2 декабря кому-то в Великобритании, но в США это будет 12 февраля. Использование формата даты и времени не помогает, поскольку это допустимая дата в обеих локализации. – macleojw

+0

DATETIME не хранится в виде строки, она хранится как количество интервалов с эпохи, поэтому в самом типе данных нет двусмысленности. DATETIME не является CHAR/VARCHAR любыми средствами. –

+0

Возможно, вы запутались, потому что он печатается по-разному в зависимости от языкового стандарта? Но это только то, как оно распечатывается. В данных нет никакой двусмысленности, которую фактически содержит DATETIME. –

0

Если ваш proc принимает дату как параметр datetime, то вы можете сделать это, чтобы подтвердить, что желаемый формат - ddmmyyyy, а не mmddyyyy. Все зависит от того, как пользователь вводил дату и как она была передана SQL.

Например: На веб-странице я мог бы добавить параметр, как это

command.Parameters.AddWithValue("@mydate",mydateVar.ToString("dd/MM/yyyy")); 

ИЛИ

command.Parameters.AddWithValue("@mydate",mydateVar.ToString("MM/dd/yyyy")); 

И SQL будет просто вставить то, что его дали, пока строка может быть приведен к дату правильно. Он не знает формат, который вы хотите использовать, поэтому он попытается использовать его в системном формате по умолчанию.

Решение, которое я использую, хотя оно может и не применимо в вашей ситуации, состоит в том, чтобы пользователи вводили все даты в любом интерфейсе, который у вас есть, в формате dd-MMM-yyyy. Затем я могу быть уверен в формате, прежде чем вставлять в БД. Я использую этот формат везде, чтобы поддерживать его все равно в приложении.

0

Вы сказали, что ожидаете, что этот хранимый процесс будет вызван непосредственно без переднего конца, а проверка прокси-файла не является вариантом.

В этом случае пользователи будут вставляя данные непосредственно, я также считаю, что в данном случае это только для внутреннего использования (как хранимая процедура будет вызываться напрямую)

Так что я думаю, что у вас есть 2 варианты

  1. если вы дисциплинированы пользователей вы можете согласиться на одном из safe formats: yyyyddmm ISO или ISO8601 гггг-мм-дд THH: мм: сс: ммм, если вам нужна часть времени, а
  2. иначе возьмите 3 параметра: год, месяц, год и выполните некоторую проверку внутри хранимой процедуры
+0

Спасибо за ваш ответ. Вы знаете какой-либо способ проверить, что дата введена в один из безопасных форматов? – macleojw

+0

Независимо от того, какие проверки вы делаете, вы не можете быть уверены, что когда пользователь входит в 20090211, он означает 11 февраля или 2 ноября, если вы четко не сообщите формат. В вашем коде вы можете предположить, что это iso-формат и просто сделать приведение в datetime, если это возвращает ошибку, отображающее сообщение об ошибке пользователю – kristof

+0

. Безопасный формат означает, что SQL Server всегда будет интерпретировать строку как yyyyddmm при преобразовании ее в тип даты и времени, независимо от того, какие у вас настройки языка – kristof

0

Я говорю взять DateTime и обучить их использовать ODBC каноническую форму даты, как в этом примере:

EXECUTE uspMyProc {d '2009-02-11'} 

Если взять дату, которую вы должны разобрать, будь то строка или год, месяц и день как отдельные целые аргументы, тогда вам нужно иметь дело с днями вне диапазона за месяц и год. Некоторые функции, которые заставляют их автоматически продвигаться или перемещаться назад в день на вас. Таким образом, трюк отправки 0 для дня и получения последнего дня предыдущего месяца. Другие возвращают ошибку. Но управлять этим материалом, вероятно, не стоит изобретать колесо.

Если вам абсолютно необходимо, потому что новички будут запускать его напрямую (для чего новички будут запускать хранимые процедуры напрямую?), Я бы взял три отдельных аргумента и передал конкатенированную дату в виде строки в формате YYYY-MM- DD через ISDATE, чтобы проверить параметры и выйти, если они недействительны.

Смежные вопросы