Sql Server строго конвертировать из varchar в datetime - PullRequest
1 голос
/ 24 февраля 2011

Я конвертирую varchar в datetime в Sql Server 2005. Могу ли я заставить Sql Server завершиться сбоем, если предоставленный varchar имеет неожиданный формат?

Пример:

select convert(datetime, '01-2010-02', 103) 

Ожидаемый результат: запрос не выполнен, поскольку 103 означает дд / мм / гггг (см. мсдн ).

Фактический результат: 2010-02-01 00: 00: 00.000

Основной целью запрашиваемого исполнения является порядок дня и месяца. Если varchar указан в формате гггг-мм-дд, то сервер Sql будет считать мм днем ​​и дд месяцем из-за порядка дня / месяца в указанном формате (дд / мм / гггг).

Примечание : я могу написать пользовательскую функцию для ручной обработки этого случая. Но я надеюсь, что такая корпоративная БД уже может работать строго с данными.

Ответы [ 3 ]

0 голосов
/ 24 февраля 2011

Всякий раз, когда SQL Server видит явного кандидата на год, он всегда будет использоваться как год.

Остальные части DM определяются из порядка в настройке DMY или в формате преобразования. Если это не так, то очень простые преобразования будут разваливаться.

Пример

set dateformat dmy
select 1 a,CONVERT(datetime, '1-2-3') b
union all
select 2,CONVERT(datetime, '2001-2-3')
union all
select 3,CONVERT(datetime, '2001-3-2')

выход

a           b
----------- -----------------------
1           2003-02-01 00:00:00.000
2           2001-03-02 00:00:00.000
3           2001-02-03 00:00:00.000

2-й и 3-й явно ставят год вперед, и это ок


EDIT

Books Online имеет это сказать http://msdn.microsoft.com/en-us/library/ms180878.aspx#StringLiteralDateandTimeFormats

Существует довольно много исключений из SET DATEFORMAT, который играет роль независимо от третьего параметра CONVERT.

  • Параметр сеанса SET DATEFORMAT не применяется ко всем числовым записям даты
  • На этот формат [ISO 8601] не влияют SET DATEFORMAT, SET LANGUAGE, языковые настройки по умолчанию для входа в систему.
  • Настройка сеанса SET DATEFORMAT не применяется при указании месяца в алфавитном порядке.
  • и т.д.

Чтобы специально проверить дд / мм / гггг, используйте вместо этого

set dateformat dmy
declare @input varchar(10) set @input = '12-2010-01'

-- convert allows the date through
select convert(datetime, @input, 103) -- 2010-01-12 00:00:00.000

-- the case below returns 0 { = invalid date }
-- this uses 8-digit format which is always interpreted YYYYMMDD regardless
-- of language or dateformat settings
select case
    when @input not like '__/__/____' then 0
    else isdate(right(@input,4)+right(left(@input,5),2)+left(@input,2))
    end
0 голосов
/ 24 февраля 2011

Вы можете сравнить дату с преобразованием в datetime и обратно. Я не знаю наверняка, есть ли какие-либо подводные камни, которые делают подобное, но мои ограниченные тесты не обнаружили никаких.

if @StrDate = convert(varchar(10), convert(datetime, @StrDate, 103) ,103)
0 голосов
/ 24 февраля 2011

Боюсь, вам нужно использовать CLR Function и воспользоваться преимуществом DateTime.TryParseExact .Не элегантное решение, но может сработать.

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