Blimey. Đây là một chủ đề thực sự hữu ích để khám phá.
Tôi vẫn thấy một số đề xuất này khó hiểu. Bất cứ khi nào tôi sử dụng value
với [1]
trong chuỗi, nó sẽ chỉ lấy giá trị đầu tiên. Và một số gợi ý được đề xuất sử dụngcross apply
(trong các thử nghiệm của tôi) chỉ mang lại quá nhiều dữ liệu.
Vì vậy, đây là ví dụ đơn giản của tôi về cách bạn tạo một xml
đối tượng, sau đó đọc các giá trị của nó vào một bảng.
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)
Và đây là đầu ra:
Cú pháp kỳ lạ, nhưng với một ví dụ phù hợp, bạn có thể dễ dàng thêm vào các hàm SQL Server của riêng mình.
Nói về điều này, đây là câu trả lời chính xác cho câu hỏi này.
Giả sử bạn có dữ liệu xml của bạn trong một @xml
biến loại xml
(như được minh họa trong ví dụ của tôi ở trên), đây là cách bạn sẽ trả về ba hàng dữ liệu từ xml được trích dẫn trong câu hỏi:
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)