Преобразование строки Sql Server в дату



Я хочу преобразовать строку следующим образом:



'10/15/2008 10:06:32 PM'


в эквивалентное значение DATETIME в Sql Server.



в Oracle, я бы сказал так:



TO_DATE('10/15/2008 10:06:32 PM','MM/DD/YYYY HH:MI:SS AM')


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

5520   10  

10 ответов:

SQL Server (2005, 2000, 7.0) не имеет гибкого или даже не гибкого способа получения произвольно структурированного datetime в строковом формате и преобразования его в тип данных datetime.

попробуй такое

Cast('7/7/2011' as datetime)

и

Convert(varchar(30),'7/7/2011',102)

посмотреть приведение и преобразование (Transact-SQL) для более подробной информации.

запустите это через процессор запросов. Это форматы даты и/или времени так и один из них должен дать вам то, что вы ищете. Это не будет трудно адаптировать:

Declare @d datetime
select @d = getdate()

select @d as OriginalDate,
convert(varchar,@d,100) as ConvertedDate,
100 as FormatValue,
'mon dd yyyy hh:miAM (or PM)' as OutputFormat
union all
select @d,convert(varchar,@d,101),101,'mm/dd/yy'
union all
select @d,convert(varchar,@d,102),102,'yy.mm.dd'
union all
select @d,convert(varchar,@d,103),103,'dd/mm/yy'
union all
select @d,convert(varchar,@d,104),104,'dd.mm.yy'
union all
select @d,convert(varchar,@d,105),105,'dd-mm-yy'
union all
select @d,convert(varchar,@d,106),106,'dd mon yy'
union all
select @d,convert(varchar,@d,107),107,'Mon dd, yy'
union all
select @d,convert(varchar,@d,108),108,'hh:mm:ss'
union all
select @d,convert(varchar,@d,109),109,'mon dd yyyy hh:mi:ss:mmmAM (or PM)'
union all
select @d,convert(varchar,@d,110),110,'mm-dd-yy'
union all
select @d,convert(varchar,@d,111),111,'yy/mm/dd'
union all
select @d,convert(varchar,@d,12),12,'yymmdd'
union all
select @d,convert(varchar,@d,112),112,'yyyymmdd'
union all
select @d,convert(varchar,@d,113),113,'dd mon yyyy hh:mm:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,114),114,'hh:mi:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,120),120,'yyyy-mm-dd hh:mi:ss(24h)'
union all
select @d,convert(varchar,@d,121),121,'yyyy-mm-dd hh:mi:ss.mmm(24h)'
union all
select @d,convert(varchar,@d,126),126,'yyyy-mm-dd Thh:mm:ss:mmm(no spaces)'

в SQL Server Denali вы сможете сделать что-то, что подходит к тому, что вы ищете. Но вы все равно не можете просто передать произвольно определенную дурацкую строку даты и ожидать, что SQL Server будет соответствовать. Вот один пример использования того, что вы опубликовали в своем собственном ответе. Функция FORMAT (), а также может принимать locales в качестве необязательного аргумента - она основана на формате .Net, поэтому большинство, если не все форматы токенов, которые вы ожидаете увидеть, будут там.

DECLARE @d DATETIME = '2008-10-13 18:45:19';

-- returns Oct-13/2008 18:45:19:
SELECT FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss');

-- returns NULL if the conversion fails:
SELECT TRY_PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);

-- returns an error if the conversion fails:
SELECT PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);

I настоятельно рекомендуем вам взять больше контроля и санировать ваши даты ввода. Дни, когда люди могут вводить даты, используя любой формат, который они хотят, в поле формы freetext, должны быть уже позади. Если кто-то входит 8/9/2011 это 9 августа или 8 сентября? Если вы заставите их выбрать дату в элементе управления календарем, приложение сможет управлять форматом. Независимо от того, насколько вы пытаетесь предсказать поведение своих пользователей, они всегда найдут более глупый способ ввести дату, которую вы не планировали для.

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


обновление для @dhergert:

SELECT TRY_PARSE('10/15/2008 10:06:32 PM' AS DATETIME USING 'en-us');
SELECT TRY_PARSE('15/10/2008 10:06:32 PM' AS DATETIME USING 'en-gb');

результаты:

2008-10-15 22:06:32.000
2008-10-15 22:06:32.000

вы все еще должны иметь эту другую важную часть информации в первую очередь. Вы не можете использовать собственный T-SQL, чтобы определить, является ли 6/9/2012 - это 9-е Июня или 6 сентября.

для этой проблемы лучшим решением, которое я использую, является наличие функции CLR в Sql Server 2005, которая использует один из DateTime.Функция Parse или ParseExact возвращает значение DateTime в указанном формате.

почему бы не попробовать

select convert(date,'10/15/2011 00:00:00',104) as [MM/dd/YYYY]

форматы дат можно найти по адресу помощник SQL Server > форматы дат SQL Server

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

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

Если вы хотите, чтобы SQL Server попытался выяснить это, просто используйте CAST CAST ('whatever' AS datetime) Однако это плохая идея в целом. Есть проблемы с международными датами, которые могут возникнуть. Итак, как вы обнаружили, чтобы избежать этих проблем, вы хотите использовать канонический формат ODBC даты. То есть формат номер 120, 20-это формат всего на два года цифр. Я не думаю, что SQL Server имеет встроенную функцию, которая позволяет предоставить пользователю заданный формат. Вы можете написать свой собственный и может даже найти один, если вы ищете в интернете.

используйте этот:

SELECT convert(datetime, '2018-10-25 20:44:11.500', 121) -- yyyy-mm-dd hh:mm:ss.mmm

и обратитесь к таблице в разделе официальная документация для преобразования кодов.

Comments

    Ничего не найдено.