【问题标题】:How to query a XML field which is not well formed?如何查询格式不正确的 XML 字段?
【发布时间】:2016-03-22 10:27:39
【问题描述】:

下面的 xml 属于一个 xml 列 AuditData。我想查询所有包含“Blondie”的记录。

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

我正在尝试这个不起作用的查询...

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

【问题讨论】:

  • (a) 您显示的 XML 格式正确。所以我不明白你的帖子的标题。 (b) 永远不要告诉我们某事“不工作”而不告诉我们它是如何失败的。这就像在不解释症状的情况下告诉医生你感觉不舒服。

标签: sql-server xml tsql sql-server-2008-r2


【解决方案1】:

我想有几个 AuditText 节点,其中一些属于 Blondie?

可以分解完整的 XML,并使用类似表格的数据在经典的 WHERE 子句中使用 LIKE 过滤它。但更好的是XQuery。最好使用.nodes() 方法,但您也可以使用.query() 甚至.value()

在这个例子中,我添加了一个根节点和几个测试节点:

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);

如果您在 AuditTable 中搜索行,您可以使用 .exist():

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;

最后,如果您的 XML 格式不正确,您可以只使用过滤器

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

或者(更准确一点)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-23
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多