如何根据SQL中XML属性名称的值过滤行

问题描述 投票:0回答:2

我的表Web.Log的列Properties包含以下内容

<properties>
  ...
  <property key="ActivityId" />
  <property key="UserName">John Doe</property>
</properties>

如何仅对包含Web.Log userName属性的行过滤John Doe表?

现在我使用

select * from Web.Log
where cast(Properties as nvarchar(max)) 
like '%<property key="UserName">John Doe</property>%'

这似乎是解决方法:-)

sql-server xml tsql xquery
2个回答
0
投票

使用XQUERY和一个EXISTS

SELECT {Columns}
FROM Web.Log L
WHERE EXISTS (SELECT 1
              FROM L.[Properties].nodes('/properties/property')p(p)
              WHERE p.p.value('(text())[1]','nvarchar(50)') = 'John Doe')

0
投票

使用本机XML方法.exist()应该更快。

首先创建一个模型场景以模拟您的问题:

DECLARE @tbl TABLE(ID INT IDENTITY, SomeText VARCHAR(100),Properties XML);
INSERT INTO @tbl VALUES('John Doe exists'
                       ,'<properties>
                            <property key="ActivityId" />
                            <property key="UserName">John Doe</property>
                         </properties>')
                        ,('John Doe doesn''t exist'
                       ,'<properties>
                            <property key="ActivityId" />
                            <property key="UserName">Someone else</property>
                         </properties>')
                        ,('John Doe exists'
                       ,'<properties>
                            <property key="ActivityId" />
                            <property key="UserName">John Doe</property>
                         </properties>');

-我们可以使用变量进行一般性过滤

DECLARE @SearchFor VARCHAR(100)='UserName';
DECLARE @FindThis  VARCHAR(100)='John Doe';

-这是查询:

SELECT *
FROM @tbl t 
WHERE t.Properties.exist('/properties/property[@key=sql:variable("@SearchFor") and text()[1]=sql:variable("@FindThis")]')=1;

简而言之:

  • 我们可以直接在WHERE子句中使用.exist()
  • 当给定的XPath至少有一个命中时,WHERE为TRUE
  • =1可以设置为=0,以便返回负值设置
  • XPath使用XQuery谓词来搜索具有给定键和值的<property>
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.