Ich habe eine Tabelle, die eine Xml
Spalte enthält :
SELECT *
FROM Sqm
Ein Beispiel für die xml
Daten einer Zeile wäre:
<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>
Bei diesen Daten möchte ich:
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 ...
Am Ende werde ich tatsächlich durchführen SUM()
, MIN()
, MAX()
Aggregation. Aber im Moment versuche ich nur, eine XML-Spalte abzufragen .
Im Pseudocode würde ich etwas versuchen wie:
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
Diese SQL-Abfrage funktioniert jedoch nicht:
Meldung 2396, Ebene 16,
Status 1, Zeile 2 XQuery [Sqm.data.query ()]: Das Attribut darf nicht außerhalb eines Elements angezeigt werden
Ich habe gejagt und es ist erstaunlich, wie schlecht dokumentiert oder beispielhaft XML-Abfragen sind. Die meisten Ressourcen fragen eine Variable ab , anstatt eine Tabelle abzufragen . was ich nicht mache. Die meisten Ressourcen verwenden XML-Abfragen nur zum Filtern und Auswählen, anstatt Werte zu lesen. Die meisten Ressourcen lesen fest codierte untergeordnete Knoten (nach Index) anstelle von tatsächlichen Werten.
Verwandte Ressourcen, die ich gelesen habe
- /programming/966441/xml-query-in-sql-server-2008
- SQL Server-Abfrage-XML-Attribut für einen Elementwert
- SQL-Abfrage von XML-Attributen
- SQL Server 2005 XQuery und XML-DML - Teil 1
- BOL: XML-Unterstützung in Microsoft SQL Server 2005
- Abfragen von XML in SQL Server
- Grundlegende SQL Server-XML-Abfrage
- BOL: query () Methode (xml Datentyp)
- XML Workshop V - Lesen von Werten aus XML-Spalten
- SQL SERVER - Einführung in das Erkennen von XML-Datentypmethoden - Ein Primer
Update: .value statt .query
Ich habe zufällig versucht .value
, anstelle von .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
Das funktioniert aber auch nicht:
Nachricht 2389, Ebene 16, Status 1, Zeile 3 XQuery [Sqm.data.value ()]:
'value ()' erfordert einen Singleton (oder eine leere Sequenz), gefundener Operand vom Typ 'xdt: untypedAtomic *'
select m.*
, den geheimen, magischen Zwischentisch zu sehen, den er konstruiert hat. Wie lautet die Syntax zum Abfragen des Werts eines Elements? zB der Wert<Metric>8675309</Metric>
ist „8675309“s
,m
undc
in dieser Abfrage darstellen?m
ist die von dernodes()
Funktion zurückgegebene Ergebnismenge ,s
ist diesqm
Tabelle selbst,c
ist eine Spalte mit dem Datentyp xml in der von dernodes()
Funktion zurückgegebenen ErgebnismengeVerwenden Sie
value
stattquery
(muss den Index des Knotens angeben, der in der XQuery zurückgegeben werden soll, und den SQL-Datentyp übergeben, der als zweiter Parameter zurückgegeben werden soll):quelle
Ich habe versucht, etwas sehr Ähnliches zu tun, aber die Knoten nicht zu verwenden. Meine XML-Struktur ist jedoch etwas anders.
Du hast es so:
Wenn es stattdessen so wäre:
Dann könnten Sie einfach diese SQL-Anweisung verwenden.
Für mich ist dies viel weniger verwirrend als die Verwendung der äußeren Anwendung oder der Kreuzanwendung.
Ich hoffe, das hilft jemand anderem, der nach einer einfacheren Lösung sucht!
quelle
/text()
nach ID usw. für Leistungssteigerung anhängenIch verstehe nicht, warum einige Leute vorschlagen , die XML in eine Wertetabelle zu verwenden
cross apply
oderouter apply
zu konvertieren. Für mich brachte das einfach viel zu viele Daten zurück.Hier ist mein Beispiel, wie Sie ein
xml
Objekt erstellen und es dann in eine Tabelle umwandeln.(Ich habe meiner XML-Zeichenfolge Leerzeichen hinzugefügt, um das Lesen zu erleichtern.)
Und hier ist die Ausgabe:
quelle
Varbinary(max)
bitte die verschachtelte Besetzung vor der XML-Besetzung?