sql-server - 如何根据 SQL 中 XML 属性名称的值过滤行
问题描述
我有包含以下内容Web.Log
的列的表Properties
<properties>
...
<property key="ActivityId" />
<property key="UserName">John Doe</property>
</properties>
如何Web.Log
仅在包含John Doe
userName 属性的行上过滤表?
现在我用
select * from Web.Log
where cast(Properties as nvarchar(max))
like '%<property key="UserName">John Doe</property>%'
这感觉像是解决方法:-)
解决方案
使用本机 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;
简而言之:
- 我们可以
.exist()
直接在 WHERE 子句中使用。 - WHERE 为 TRUE,当给定 XPath 至少有一次命中时
=1
可以设置为以=0
返回负集- XPath 使用 XQuery 谓词来搜索
<property>
具有给定键和值的 a。
推荐阅读
- javascript - 将 '04/21/19' 转换为 '2019-04-14T08:54:27.096Z' 格式
- tf-idf - 如何解决“无法索引具有零特征的语料库”错误
- angular - Kubernetes Ingress 部署 Angular 资产(图片)不显示
- rest - 如何从 PowerShell 中的请求中获取 StatusCode
- pine-script - 如何将此代码从 Pinescript 1.0 版迁移到 3.0 版
- python - 排序算法可视化:如何从紧密循环中提取值以动画画布
- c# - 获取CancellationToken的剩余时间
- python - Python - 从列表中提取并重塑
- wget - 如何使用wget下载到某个目录
- angular - 放大 Angular 7 构建错误 - 'NgModule' 调用'ɵmakeDecorator'