2016-03-22 6 views
0

Die folgende XML gehört zu einer XML-Spalte AuditData. Ich möchte alle Datensätze mit 'Blondie' darin abfragen.Wie kann man ein XML-Feld abfragen, das nicht gut gebildet ist?

<AuditText Username="Blondie" CustomerGUID="xxxxxxxxxx3C4B35821FC0" IPAddress="xx.xxx.xxx.xx" /> 

ich diese Abfrage bin versucht, die ...

select top 10 * from t_audit (nolock) 
and AuditData.value('(/Username)[1]','varchar(max)') like 'Blondie' 
+1

(a) Die XML Sie zeigen, ist wohlgeformt ist. Also ich verstehe den Titel deines Posts nicht. (b) Sagen Sie uns nie, dass etwas "nicht funktioniert", ohne uns zu sagen, wie es scheitert. Es ist, als würde man dem Arzt sagen, dass man sich nicht wohl fühlt, ohne die Symptome zu erklären. –

Antwort

2

I gibt es mehrere AuditText-Knoten annehmen, nicht funktioniert und einige von ihnen zu Blondie gehören?

Sie konnte zerkleinern das vollständige XML und verwenden Sie die tabellenartige Daten diese in einer klassischen WHERE Klausel mit einem LIKE zu filtern. Aber viel besser war XQuery. Am besten ist es, die .nodes() Methode zu verwenden, aber Sie können auch .query() oder sogar .value() verwenden.

In diesem Beispiel habe ich ein Wurzelknoten und mehrere Testknoten:

DECLARE @xml XML= 
'<root> 
<AuditText Username="Blondie" CustomerGUID="xxxxxxxxxx3C4B35821FC0" IPAddress="xx.xxx.xxx.xx" /> 
<AuditText Username="Test1" CustomerGUID="xxxxxxxxxx11111111" IPAddress="xx.xxx.111.11" /> 
<AuditText Username="Blondie" CustomerGUID="xxxxxxxxxx3C4B35821FC0" IPAddress="xx.xxx.xxx.xx" /> 
<AuditText Username="Test2" CustomerGUID="xxxxxxxxxx222222222" IPAddress="xx.xxx.222.22" /> 
</root> 
'; 

SELECT Blondie.value('@CustomerGUID','varchar(max)') AS CustomerGuid --you might set the type to "uniqueidentifier", if the value is a valid GUID 
FROM @xml.nodes('/root/AuditText[@Username="Blondie"]') AS Only(Blondie); 

--This is the way to insert your search string via variable 
DECLARE @Username VARCHAR(100)='Test1'; 
SELECT MyUser.value('@CustomerGUID','varchar(max)') 
FROM @xml.nodes('/root/AuditText[@Username=sql:variable("@Username")]') AS Only(MyUser); 

Wenn Sie für die Zeilen in Ihrer AuditTable suchen Sie .exist() verwenden könnten:

CREATE TABLE #t_audit(ID INT IDENTITY,AuditData XML); 
INSERT INTO #t_audit(AuditData) VALUES 
('<AuditText Username="Blondie" CustomerGUID="xxxxxxxxxx3C4B35821FC0" IPAddress="xx.xxx.xxx.xx" />') 
,('<AuditText Username="Blondie" CustomerGUID="xxxxxxxxxx3C4B35821FC0" IPAddress="xx.xxx.xxx.xx" />') 
,('<AuditText Username="Test1" CustomerGUID="xxxxxxxxxx11111111" IPAddress="xx.xxx.111.11" />') 
,('<AuditText Username="Blondie" CustomerGUID="xxxxxxxxxx3C4B35821FC0" IPAddress="xx.xxx.xxx.xx" />') 
,('<AuditText Username="Test2" CustomerGUID="xxxxxxxxxx222222222" IPAddress="xx.xxx.222.22" />'); 


SELECT * 
FROM #t_audit 
WHERE AuditData.exist('AuditText[@Username="Blondie"]')=1; 

--DROP TABLE #t_audit; 

Und schließlich, wenn Ihr XML ist nicht gut gebildet, könnten Sie nur mit

WHERE CAST(AuditData AS VARCHAR(MAX)) LIKE '%Blondie%' 
filtern

oder (etwas genauer)

WHERE CAST(AuditData AS VARCHAR(MAX)) LIKE '% Username="Blondie"%' 
Verwandte Themen