À l'aide d'OPENXML dans SQL Server 2008 stockées proc - INSÉRER la commande diffère de document XML
Je suis à l'aide de SQL Server 2008, XML-analyse des capacités pour parcourir un document XML et d'effectuer une INSERTION de chaque élément.
Cependant, ma procédure stockée s'affiche à l'insertion de chaque élément dans la table dans un ordre qui diffère de l'ordre dans le document.
En outre, le plus de fois j'ai essayer cela, l'INSERT de commande semble changer.
Voici un exemple de document XML, rien de trop envie d'aller sur ici.
<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>
La procédure stockée a quelques opérations qui ont lieu, mais j'ai commenté d'autres parties ne laissant que le SQL qui insère les <t/>
éléments, puis la <tv/>
éléments.
Le SQL dans la procédure stockée est comme suit.
(@xmlTransaction
est un NVARCHAR (MAX)
entrée param contenant le XML ci-dessus)
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
Devrait être assez simple. Et pourtant, si j'ai une requête les résultats, ils ne sont pas dans le même ordre que le document XML. La deuxième instruction INSERT pour le <tv/>
éléments ne stocker les éléments dans un deuxième tableau dans l'ordre correct, mais le <t/>
éléments sont pas stockées dans la table dans l'ordre correct.
Quelqu'un peut-il m'expliquer pourquoi le <t/>
éléments ne sont pas Insérées dans la table dans le même ordre qu'ils apparaissent dans le document XML?
Vous devez vous connecter pour publier un commentaire.
Si j'utilise le natif de support XQuery SQL Server au lieu de "l'héritage" OPENXML choses, puis il semblerait que le
<t>
les nœuds sont en effet insérés dans la table dans l'ordre où ils apparaissent dans le document XML.J'ai utilisé le code quelque chose comme ceci:
La même chose pourrait être fait pour la
<tv>
sous-nœuds, trop.Aussi loin que je peux voir, la documentation sur OPENXML ne garantit rien sur l'ordre. Et l'ordre n'est pas garanti dans une table relationnelle soit. Alors pourquoi ne pas simplement "commande par" une certaine colonne pour obtenir la commande que vous souhaitez? C'est toujours la façon dont vous appliquez la commande sql.
Je ne vois pas pourquoi vous êtes l'extraction de la encryptedAccountId attribut séparément. Pourquoi ne pas l'insérer dans la déclaration de maininsert?
Sans rapport avec astuce, si votre opération d'insertion est de la génération d'une identité, vous pouvez accrocher une copie pour vos valeurs insertion par l'adhésion à ce parent, table sur "../@id". Même si vous n'avez pas besoin de rien d'autre de la table parent, cela semble une bonne idée, afin de s'assurer qu'aucun de vos transactions insère échoué.
Astuce exemple: