Проверка параметра даты в хранимой процедуре SQL Server - PullRequest
2 голосов
/ 11 февраля 2009

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

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

Ответы [ 6 ]

4 голосов
/ 11 февраля 2009

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


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

yyyy-MM-dd HH:mm:ss

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

4 голосов
/ 11 февраля 2009

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

create proc dbo.Sproc
    @date datetime
as
    ...
1 голос
/ 20 февраля 2009

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

0 голосов
/ 12 февраля 2009

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

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

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

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

0 голосов
/ 11 февраля 2009

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

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

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

  1. если у вас есть дисциплинированные пользователи, вы можете согласиться на один из безопасных форматов : ISO ггггдмм или ISO8601 гггг-мм-дд чч: мм: сс: ммм, если вам также нужна временная часть
  2. в противном случае принять 3 параметра: год, месяц, год и выполнить некоторую проверку в хранимой процедуре
0 голосов
/ 11 февраля 2009

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

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

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

OR

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...