Accidenti. Questo è stato un thread davvero utile da scoprire.
Ho ancora trovato alcuni di questi suggerimenti confusi. Ogni volta che ho usato value
con [1]
nella stringa, recuperava solo il primo valore. E alcuni suggerimenti consigliavano di utilizzare cross apply
che (nei miei test) hanno riportato troppi dati.
Quindi, ecco il mio semplice esempio di come creare un xml
oggetto, quindi leggere i suoi valori in una tabella.
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)
Ed ecco l'output:
È una sintassi bizzarra, ma con un esempio decente è abbastanza facile da aggiungere alle proprie funzioni di SQL Server.
A proposito, ecco la risposta corretta a questa domanda.
Supponendo che tu abbia i tuoi dati xml in una @xml
variabile di tipo xml
(come dimostrato nel mio esempio sopra), ecco come restituiresti le tre righe di dati dall'xml citato nella domanda:
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)