#sql-server
#sql-сервер
Вопрос:
SQL Server 2016
Я отправляю массовые записи через xml. У меня следующий запрос:
DECLARE @xmlString VARCHAR(4000);
SET @xmlString = N'
<Customers>
<OrderID>10248</OrderID>
<CustomerID>VINET</CustomerID>
<CreateDate>10/7/2016 7:31:06 AM</CreateDate>
</Customers>
';
DECLARE @xml XML;
SET @xml = CONVERT(XML, @xmlString);
INSERT INTO [test].dbo.[customers]
( [OrderID] ,
[CustomerID] ,
[CreateDate]
)
SELECT T.Customer.value('(OrderID)[1]', 'INT') AS OrderID ,
T.Customer.value('(CustomerID)[1]', 'nvarchar(20)') AS CustomerID ,
T.Customer.value('(CreateDate)[1]', 'DATETIME') AS CreateDate
FROM @xml.nodes('Customers') AS T ( Customer );
Если я удалю поле CreateDate, оно загрузится просто отлично. Однако, если я оставляю поле CreateDate в, я получаю эту ошибку:
Ошибка преобразования Msg 241, уровень 16, состояние 1, строка 35 при преобразовании даты и / или времени из символьной строки.
CreateDate — это поле даты И времени.
Вот таблица:
CREATE TABLE [dbo].[Customers](
[OrderID] [INT] NULL,
[CreateDate] [DATETIME] NOT NULL,
[CustomerID] [NVARCHAR](10) NULL
) ON [PRIMARY]
Какое преобразование мне не хватает для загрузки даты / времени в мою таблицу через xml? Спасибо
Комментарии:
1. Если возможно, вернитесь к тому, кто создал этот XML для вас, и скажите им использовать ISO 8601 в качестве формата даты / времени для экспорта.
2016-10-07 07:31:06
имеет гораздо меньше проблем с преобразованием. Предполагается, что 10/7 равно ММ / ДД, как, кажется, указывает «AM»… вы никогда не можете быть уверены в локальных форматах.2. @jeroen — я создаю xml. Я попробовал ISO 8601 (т.е. 2006-04-18T09: 58: 04.570), и это все равно не удалось
3. Я запустил этот код на своем компьютере (без вставки), он показывает мне правильную дату и время из XML. Может быть, что-то с таблицей назначения? Можете ли вы показать его сценарий создания?
4. Что такое псевдоним второго столбца в предложении SELECT? опечатка?
5. СОЗДАЙТЕ ТАБЛИЦУ [dbo]. [Customers]( [OrderID] [INT] NULL, [CreateDate] [DATETIME] NOT NULL, [CustomerID] [NCHAR](10) NULL) НА [ОСНОВНОЙ]
Ответ №1:
В своем комментарии вы говорите, что я создаю xml. Как вы это делаете?
В правильно созданном XML значение даты / времени должно быть ISO8601.
Ваши несколько строк кода показывают, что вы не думаете в XML. XML — это не простой текст с некоторыми дополнительными символами…
Тем не менее, ваш формат можно преобразовать с помощью кода 131 для dd/mm/yyyy
или 101 для mm/dd/yyyy
, но вы не должны этого делать!
DECLARE @xml XML=
N'
<Customers>
<OrderID>10248</OrderID>
<CustomerID>VINET</CustomerID>
<CreateDate>10/7/2016 7:31:06 AM</CreateDate>
</Customers>
';
SELECT c.value('OrderID[1]','int') AS OrderID
,c.value('CustomerID[1]','nvarchar(100)') AS CustomerID
,CONVERT(DATETIME,c.value('CreateDate[1]','nvarchar(100)'),101) AS CreateDate
FROM @xml.nodes('Customers') AS A(c)
Лучше попробуйте это так
DECLARE @xml2 XML=
N'
<Customers>
<OrderID>10248</OrderID>
<CustomerID>VINET</CustomerID>
<CreateDate>2016-10-07T07:31:06</CreateDate>
</Customers>
';
SELECT c.value('OrderID[1]','int') AS OrderID
,c.value('CustomerID[1]','nvarchar(100)') AS CustomerID
,c.value('CreateDate[1]','datetime') AS CreateDate
FROM @xml2.nodes('Customers') AS A(c)
Комментарии:
1. В этой статье говорится то же самое p2p.wrox.com /. … Я отформатировал дату, как указано выше, и это сработало. Но я соглашусь с ответом @GauravKP. Я могу оставить свою дату в точном формате, как в моем вопросе, и это работает. Спасибо, я проголосую за это.
2. @BoundForGlory, ты можешь делать что хочешь, но тебе следует изменить свой ник на BoundToTroubles 🙂
3. @BoundForGlory, вам следует перепроверить свои выходные данные на день старше 12. Данный формат может выглядеть корректно, но может ошибочно указывать месяц как дни. Это действительно плохая привычка полагаться на культурные форматы даты и времени!
4. Я понимаю, что вы говорите, и я ценю вашу заботу. То, что я показываю, — это всего лишь пример моего приложения. Это НЕ код производственного уровня. Я просто хотел преобразовать дату / время. Спасибо.
Ответ №2:
Используйте следующее, если дата XML указана в формате мм / дд / гггг
CONVERT(datetime, T.Customer.value('(CreateDate)[1]', 'nvarchar(50)'), 101) AS CreateDate
Если дата в XML находится в каком-либо другом формате, например, дд / мм / гггг — пожалуйста, перейдите по ссылке ниже, чтобы узнать, что следует поместить вместо 101
Комментарии:
1. Извините, произошла опечатка ‘nvarchar (50)’ должен быть там в
T.Customer.value('(CreateDate)[1]', 'nvarchar(50)')
2. Отлично!… Большое вам спасибо
3. Извините за это, но этот ответ далек от совершенства . Это может сработать, но это абсолютно неправильный совет со значениями даты и времени в XML. голосуйте против с моей стороны…
4. @Shnugo: вы можете отклонять голосование столько раз, сколько захотите, но я ответил только на конкретное требование в случае, если OP знает формат культуры даты и времени, который поступает в XML, он будет работать независимо от даты и времени системы SQL Server. Допустимый входной XML-файл является точкой входа, весь ответ завершится ошибкой, если вместо даты он будет содержать ненужное или нулевое значение. Надеюсь, вы поняли суть. . — Ничто не идеально.
5. @GauravKP — Я согласен. Я объяснил Шнуго, что опубликовал пример своего кода. И никто не хочет лучших практик больше, чем я. Но, чтобы понизить голос и ответить, это мелко. Ваше решение сделало именно то, что я хотел.