Я использую возможности XML-синтаксического анализа SQL Server 2008 для итерации через XML-документ и выполнения INSERT каждого элемента.Использование OPENXML в SQL Server 2008 сохраненный порядок proc-INSERT отличается от XML-документа
Однако моя хранимая процедура, кажется, вставляет каждый элемент в таблицу в порядке, который отличается от порядка в документе.
Кроме того, чем больше раз я пытаюсь это сделать, порядок INSERT, похоже, меняется.
Вот пример XML-документа - здесь нет ничего необычного.
<ts>
<t id="36a3c8c1-b958-42f0-82d1-dfa6bf9b99a1" encryptedAccountId="fQ/XF8lpeR9wEDUV3yMzvQ==" uploaded="2012-04-03T15:49:19.9615097Z" visible="1">
<tv fieldId="301" officialValue="0, 0" friendlyValue="0, 0" />
<tv fieldId="302" officialValue="0, 1" friendlyValue="0, 1" />
<tv fieldId="303" officialValue="0, 2" friendlyValue="0, 2" />
<tv fieldId="304" officialValue="0, 3" friendlyValue="0, 3" />
<tv fieldId="305" officialValue="0, 4" friendlyValue="0, 4" />
<tv fieldId="306" officialValue="0, 5" friendlyValue="0, 5" />
</t>
<t id="9d56d082-4b6a-4bdf-a7a2-f5c6af88344e" encryptedAccountId="fQ/XF8lpeR9wEDUV3yMzvQ==" uploaded="2012-04-03T15:49:19.9615097Z" visible="1">
<tv fieldId="301" officialValue="1, 0" friendlyValue="1, 0" />
<tv fieldId="302" officialValue="1, 1" friendlyValue="1, 1" />
<tv fieldId="303" officialValue="1, 2" friendlyValue="1, 2" />
<tv fieldId="304" officialValue="1, 3" friendlyValue="1, 3" />
<tv fieldId="305" officialValue="1, 4" friendlyValue="1, 4" />
<tv fieldId="306" officialValue="1, 5" friendlyValue="1, 5" />
</t>
<t id="27db47a3-ad3f-4279-8f4f-0a8944ce32d4" encryptedAccountId="fQ/XF8lpeR9wEDUV3yMzvQ==" uploaded="2012-04-03T15:49:19.9615097Z" visible="1">
<tv fieldId="301" officialValue="2, 0" friendlyValue="2, 0" />
<tv fieldId="302" officialValue="2, 1" friendlyValue="2, 1" />
<tv fieldId="303" officialValue="2, 2" friendlyValue="2, 2" />
<tv fieldId="304" officialValue="2, 3" friendlyValue="2, 3" />
<tv fieldId="305" officialValue="2, 4" friendlyValue="2, 4" />
<tv fieldId="306" officialValue="2, 5" friendlyValue="2, 5" />
</t>
<t id="867ea26b-0341-4d60-ac48-f305492a60f0" encryptedAccountId="fQ/XF8lpeR9wEDUV3yMzvQ==" uploaded="2012-04-03T15:49:19.9615097Z" visible="1">
<tv fieldId="301" officialValue="3, 0" friendlyValue="3, 0" />
<tv fieldId="302" officialValue="3, 1" friendlyValue="3, 1" />
<tv fieldId="303" officialValue="3, 2" friendlyValue="3, 2" />
<tv fieldId="304" officialValue="3, 3" friendlyValue="3, 3" />
<tv fieldId="305" officialValue="3, 4" friendlyValue="3, 4" />
<tv fieldId="306" officialValue="3, 5" friendlyValue="3, 5" />
</t>
</ts>
Хранимая процедура имеет несколько операций, протекающие, но я закомментированная другие части, оставляя только SQL, который вставляет в <t/>
элементы, а затем <tv/>
элементы.
SQL в хранимой процедуре выглядит следующим образом.
(@xmlTransaction
является NVARCHAR (MAX)
входа парами, содержащих выше XML)
BEGIN
SET NOCOUNT ON;
DECLARE @encryptedAccountID AS VARCHAR(200)
BEGIN TRANSACTION
BEGIN TRY
DECLARE @Handle AS INT
DECLARE @TransactionCount AS INT
EXEC sp_xml_preparedocument @Handle OUTPUT, @xmlTransaction
/* encryptedAccountId is always the same for each @xmlTransaction param */
/* Just take the value from the first <t/> element */
SET @encryptedAccountID = (SELECT eID FROM OPENXML (@Handle, '/ts/t[1]', 2) WITH (eID VARCHAR '@encryptedAccountId'))
/* Go through each <t/> element in the XML document and INSERT */
INSERT INTO
[Transactions]
(
[ID],
[EncryptedAccountID]
)
SELECT
*
FROM
OPENXML (@Handle, '/ts/t', 2)
WITH
(
rID UNIQUEIDENTIFIER '@id',
rEncryptedAccountID VARCHAR (200) '@encryptedAccountId'
)
/* Loop through each TransactionValue in the XML document and INSERT */
INSERT INTO
[TransactionValues]
(
FieldID,
TransactionID,
OfficialValue,
FriendlyValue
)
SELECT
*
FROM
OPENXML (@Handle, '/ts/t/tv', 2)
WITH
(
rFieldID INT '@fieldId',
rTransactionID UNIQUEIDENTIFIER '../@id',
rOfficialValue NVARCHAR (500) '@officialValue',
rFriendlyValue NVARCHAR (500) '@friendlyValue'
)
/* Dispose of the XML document */
EXEC sp_xml_removedocument @Handle
COMMIT TRANSACTION
END TRY
BEGIN CATCH
RETURN @@ERROR
ROLLBACK TRANSACTION
END CATCH
END
Должен быть довольно просто. И все же, если я запрашиваю результаты, они не совпадают с документом XML. Второй оператор INSERT для элементов <tv/>
делает хранит элементы во второй таблице в правильном порядке, но элементы <t/>
: не хранятся в таблице в правильном порядке.
Может ли кто-нибудь объяснить мне, почему элементы <t/>
НЕ ВСТАВЛЯЕТСЯ в таблицу в том же порядке, что и в документе XML?
Я совершенно не осведомлен об этом XQuery в SQL Server и думал, что OPENXML - единственный способ добиться этого. Теперь я буду исследовать XQuery и отчитаться. – awj
Я потратил час, пытаясь заставить это работать, но не может. Я не могу найти никаких учебников или руководств с синтаксисом, подобным вашим - все страницы, которые я могу найти, относятся к тому, как изменять существующие поля XML. Я пробовал ваш SQL, но получаю сообщение «Узлы XMLDT-метода» могут быть вызваны только в столбцах типа xml ». Конечно, мне не нужно менять типы полей для вставки этих данных? Тем более, что вы все еще объявляли типы для «id» и «encryptedAccountId» [не разрешали использовать символ «at» в комментариях]. Вот скриншот того, что я пытался сделать: http://screencast.com/t/CToJqYqH55RH – awj
В моем тестировании производительности openxml избили xquery огромным запасом. Зависит от вашего документа. Каждая колонка, которую вы запрашиваете с помощью xquery, создает таблицу, которая затем внутренне соединяется с каждым другим столбцом, чтобы дать вам таблицу. OpenXML - подборщик специальных символов. Я использую только xquery, когда у меня есть раздражающие данные, такие как имена с 'и &. –