У меня есть таблица, содержащая столбец Xml:
SELECT * 
FROM Sqm
 
Образец данных Xml строки:
<Sqm version="1.2">
  <Metrics>
    <Metric id="TransactionCleanupThread.RecordUsedTransactionShift" type="timer" unit="µs" count="1" sum="21490"   average="21490"   minValue="73701"    maxValue="73701"                               >73701</Metric>
    <Metric id="TransactionCleanupThread.RefundOldTrans"             type="timer" unit="µs" count="1" sum="184487"  average="184487"  minValue="632704"   maxValue="632704"                              >632704</Metric>
    <Metric id="Database.CreateConnection_SaveContextUserGUID"       type="timer" unit="µs" count="2" sum="7562"    average="3781"    minValue="12928"    maxValue="13006"    standardDeviation="16"     >12967</Metric>
    <Metric id="Global.CurrentUser"                                  type="timer" unit="µs" count="6" sum="4022464" average="670411"  minValue="15"       maxValue="13794345" standardDeviation="1642047">2299194</Metric>
    <Metric id="Global.CurrentUser_FetchIdentityFromDatabase"        type="timer" unit="µs" count="1" sum="4010057" average="4010057" minValue="13752614" maxValue="13752614"                            >13752614</Metric>
  </Metrics>
</Sqm>
В случае этих данных я бы хотел:
SqmId  id                                                   type   unit  count  sum      minValue  maxValue  standardDeviation  Value
=====  ===================================================  =====  ====  =====  ======   ========  ========  =================  ======
1      TransactionCleanupThread.RecordUsedTransactionShift  timer  µs    1      21490    73701     73701     NULL               73701
1      TransactionCleanupThread.RefundOldTrans              timer  µs    1      184487   632704    632704    NULL               632704
1      Database.CreateConnection_SaveContextUserGUID        timer  µs    2      7562     12928     13006     16                 12967
1      Global.CurrentUser                                   timer  µs    6      4022464  15        13794345  1642047            2299194
1      Global.CurrentUser_FetchIdentityFromDatabase         timer  µs    1      4010057  13752614  13752614  NULL               13752614
2      ...
В конце концов, я на самом деле выполняю агрегацию SUM(), MIN(), MAX(). Но сейчас я просто пытаюсь запросить столбец xml.
В псевдокоде я бы попробовал что-то вроде:
SELECT
    SqmId,
    Data.query('/Sqm/Metrics/Metric/@id') AS id,
    Data.query('/Sqm/Metrics/Metric/@type') AS type,
    Data.query('/Sqm/Metrics/Metric/@unit') AS unit,
    Data.query('/Sqm/Metrics/Metric/@sum') AS sum,
    Data.query('/Sqm/Metrics/Metric/@count') AS count,
    Data.query('/Sqm/Metrics/Metric/@minValue') AS minValue,
    Data.query('/Sqm/Metrics/Metric/@maxValue') AS maxValue,
    Data.query('/Sqm/Metrics/Metric/@standardDeviation') AS standardDeviation,
    Data.query('/Sqm/Metrics/Metric') AS value
FROM Sqm
Но этот SQL-запрос не работает:
Msg 2396, уровень 16, состояние 1, строка 2
XQuery [Sqm.data.query()]: Атрибут может не отображаться вне элемента
Я охотился, и это удивительно, насколько плохо документированы или анализируются запросы Xml. Большинство ресурсов, а не запрос таблицы , запрашивают переменную ; которого я не делаю. Большинство ресурсов используют только xml-запрос для фильтрации и выбора, а не для чтения значений. Большинство ресурсов читают жестко закодированные дочерние узлы (по индексу), а не фактические значения.
Связанные ресурсы, которые я читал
- https://stackoverflow.com/info/966441/xml-query-in-sql-server-2008
 - Атрибут xml запроса SQL Server для значения элемента
 - SQL-запрос атрибутов XML
 - SQL Server 2005 XQuery и XML-DML - часть 1
 - BOL: поддержка XML в Microsoft SQL Server 2005
 - Запрос XML в SQL Server
 - Основной запрос XML SQL Server
 - BOL: query() Метод (xml Тип данных)
 - XML Workshop V - Чтение значений из столбцов XML
 - SQL SERVER - Введение в обнаружение методов типа данных XML - Primer
 
Обновление:.value, а не .query
Я попытался случайным образом использовать .value вместо .query:
SELECT
    Sqm.SqmId,
    Data.value('/Sqm/Metrics/Metric/@id', 'varchar(max)') AS id,
    Data.value('/Sqm/Metrics/Metric/@type', 'varchar(max)') AS type,
    Data.value('/Sqm/Metrics/Metric/@unit', 'varchar(max)') AS unit,
    Data.value('/Sqm/Metrics/Metric/@sum', 'varchar(max)') AS sum,
    Data.value('/Sqm/Metrics/Metric/@count', 'varchar(max)') AS count,
    Data.value('/Sqm/Metrics/Metric/@minValue', 'varchar(max)') AS minValue,
    Data.value('/Sqm/Metrics/Metric/@maxValue', 'varchar(max)') AS maxValue,
    Data.value('/Sqm/Metrics/Metric/@standardDeviation', 'varchar(max)') AS standardDeviation,
    Data.value('/Sqm/Metrics/Metric', 'varchar(max)') AS value
FROM Sqm
Но это также не работает:
Msg 2389, Уровень 16, Состояние 1, Строка 3 XQuery [Sqm.data.value()]:
'value()' требует одиночного (или пустой последовательности), найденного операнда type 'xdt: untypedAtomic *'
