Как запросить значения и атрибуты Xml из таблицы в SQL Server?
у меня есть таблица, которая содержит
4 ответов
на самом деле вы близки к вашей цели, вам просто нужно использовать nodes () метод для разделения строк, а затем получить значения:
select
s.SqmId,
m.c.value('@id', 'varchar(max)') as id,
m.c.value('@type', 'varchar(max)') as type,
m.c.value('@unit', 'varchar(max)') as unit,
m.c.value('@sum', 'varchar(max)') as [sum],
m.c.value('@count', 'varchar(max)') as [count],
m.c.value('@minValue', 'varchar(max)') as minValue,
m.c.value('@maxValue', 'varchar(max)') as maxValue,
m.c.value('.', 'nvarchar(max)') as Value,
m.c.value('(text())[1]', 'nvarchar(max)') as Value2
from sqm as s
outer apply s.data.nodes('Sqm/Metrics/Metric') as m(c)
использовать value
вместо query
(необходимо указать индекс узла для возврата в XQuery, а также передать тип данных sql для возврата в качестве второго параметра):
select
xt.Id
, x.m.value( '@id[1]', 'varchar(max)' ) MetricId
from
XmlTest xt
cross apply xt.XmlData.nodes( '/Sqm/Metrics/Metric' ) x(m)
Я пытаюсь сделать что-то очень похожее, но не используя узлы. Однако моя структура xml немного отличается.
У вас это так:
<Metrics>
<Metric id="TransactionCleanupThread.RefundOldTrans" type="timer" ...>
Если бы это было так:
<Metrics>
<Metric>
<id>TransactionCleanupThread.RefundOldTrans</id>
<type>timer</type>
.
.
.
тогда вы можете просто использовать этот оператор SQL.
SELECT
Sqm.SqmId,
Data.value('/Sqm/Metrics/Metric/id)[1]', 'varchar(max)') as id,
Data.value('/Sqm/Metrics/Metric/type)[1]', 'varchar(max)') AS type,
Data.value('/Sqm/Metrics/Metric/unit)[1]', 'varchar(max)') AS unit,
Data.value('/Sqm/Metrics/Metric/sum)[1]', 'varchar(max)') AS sum,
Data.value('/Sqm/Metrics/Metric/count)[1]', 'varchar(max)') AS count,
Data.value('/Sqm/Metrics/Metric/minValue)[1]', 'varchar(max)') AS minValue,
Data.value('/Sqm/Metrics/Metric/maxValue)[1]', 'varchar(max)') AS maxValue,
Data.value('/Sqm/Metrics/Metric/stdDeviation)[1]', 'varchar(max)') AS stdDeviation,
FROM Sqm
для меня это гораздо менее запутанно, чем использование внешнего применения или перекрестного применения.
Я надеюсь, что это поможет кому-то еще искать более простое решение!
Я не понимаю, почему некоторые люди предлагают использовать cross apply
или outer apply
для преобразования XML в таблицу значений. Для меня это просто принесло слишком много данных.
вот мой пример того, как вы создадите xml
объект, затем превратите его в таблицу.
(Я добавил пробелы в строку xml, просто чтобы было легче читать.)
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)
и вот результат: