Blimey. C'était un fil vraiment utile à découvrir.
J'ai toujours trouvé certaines de ces suggestions déroutantes. Chaque fois que j'utilisais value
avec [1]
dans la chaîne, il ne récupérait que la première valeur. Et quelques suggestions recommandées d'utilisercross apply
ce qui (dans mes tests) a juste rapporté beaucoup trop de données.
Alors, voici mon exemple simple de la façon dont vous créez un xml
objet, puis lisez ses valeurs dans une table.
DECLARE @str nvarchar(2000)
SET @str = ''
SET @str = @str + '<users>'
SET @str = @str + ' <user>'
SET @str = @str + ' <firstName>Mike</firstName>'
SET @str = @str + ' <lastName>Gledhill</lastName>'
SET @str = @str + ' <age>31</age>'
SET @str = @str + ' </user>'
SET @str = @str + ' <user>'
SET @str = @str + ' <firstName>Mark</firstName>'
SET @str = @str + ' <lastName>Stevens</lastName>'
SET @str = @str + ' <age>42</age>'
SET @str = @str + ' </user>'
SET @str = @str + ' <user>'
SET @str = @str + ' <firstName>Sarah</firstName>'
SET @str = @str + ' <lastName>Brown</lastName>'
SET @str = @str + ' <age>23</age>'
SET @str = @str + ' </user>'
SET @str = @str + '</users>'
DECLARE @xml xml
SELECT @xml = CAST(CAST(@str AS VARBINARY(MAX)) AS XML)
-- Iterate through each of the "users\user" records in our XML
SELECT
x.Rec.query('./firstName').value('.', 'nvarchar(2000)') AS 'FirstName',
x.Rec.query('./lastName').value('.', 'nvarchar(2000)') AS 'LastName',
x.Rec.query('./age').value('.', 'int') AS 'Age'
FROM @xml.nodes('/users/user') as x(Rec)
Et voici la sortie:
C'est une syntaxe bizarre, mais avec un exemple décent, il est assez facile d'ajouter à vos propres fonctions SQL Server.
En parlant de cela, voici la bonne réponse à cette question.
En supposant que vous ayez vos données xml dans une @xml
variable de type xml
(comme illustré dans mon exemple ci-dessus), voici comment vous renverriez les trois lignes de données du xml cité dans la question:
SELECT
x.Rec.query('./firstName').value('.', 'nvarchar(2000)') AS 'FirstName',
x.Rec.query('./lastName').value('.', 'nvarchar(2000)') AS 'LastName'
FROM @xml.nodes('/person') as x(Rec)