J'ai une table qui contient une colonne Xml
:
SELECT *
FROM Sqm
Un exemple des données xml
d'une ligne serait :
73701
632704
12967
2299194
13752614
Dans le cas de ces données, je voudrais :
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 ...
À la fin, je vais en fait effectuer des agrégations avec SUM()
, MIN()
, MAX()
. Mais pour l'instant, j'essaie simplement d'effectuer une requête sur une colonne xml.
En pseudo-code, j'essaierais quelque chose comme :
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
Mais cette requête SQL ne fonctionne pas :
Msg 2396, Niveau 16, État 1, Ligne 2
XQuery [Sqm.data.query()] : L'attribut ne peut pas apparaître en dehors d'un élément
J'ai cherché, et il est incroyable de voir à quel point la consultation de Xml est mal documentée ou illustrée. La plupart des ressources, plutôt que de requêter une table, requêtent une variable ; ce que je ne fais pas. La plupart des ressources utilisent la consultation xml pour le filtrage et la sélection, plutôt que pour la lecture des valeurs. La plupart des ressources lisent des nœuds enfants codés en dur (par index), plutôt que des valeurs réelles.
Ressources connexes que j'ai lues
- https://stackoverflow.com/questions/966441/xml-query-in-sql-server-2008
- SQL Server query xml attribute for an element value
- SQL querying XML attributes
- SQL Server 2005 XQuery and XML-DML - Part 1
- BOL: XML Support in Microsoft SQL Server 2005
- Querying XML in SQL Server
- Basic SQL Server XML Querying
- BOL: query() Method (xml Data Type)
- XML Workshop V - Reading Values from XML Columns
- SQL SERVER – Introduction to Discovering XML Data Type Methods – A Primer
Mise à jour : .value plutôt que .query
J'ai essayé aléatoirement d'utiliser .value
, à la place de .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
Mais cela ne fonctionne pas non plus :
Msg 2389, Niveau 16, État 1, Ligne 3 XQuery [Sqm.data.value()] :
'value()' exige un singleton (ou une séquence vide), trouvé un opérande de type 'xdt:untypedAtomic *'