简体   繁体   English

Select数据在SQL表中XML数据列上使用WHERE条件

[英]Select data using WHERE condition on XML data column in SQL table

I have a table that lists some user details.我有一个列出一些用户详细信息的表。

ID ID GUID GUID Username用户名 Password密码 Data数据
1 1个 a2a8s7d4d a2a8s7d4d xswe xswe xxxxxx xxxxxx XML XML
2 2个 aer335mla aer335mla user用户 xxxxxx xxxxxx XML XML

The Data column contains data using XML. Below is a sample from the table.数据列包含使用 XML 的数据。下面是表格中的示例。

<UserInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ComponentFramework">
<ActiveDirectoryUser>false</ActiveDirectoryUser>
<CanUpdateMasterData>false</CanUpdateMasterData>
<CanUploadFiles>false</CanUploadFiles>
<ChangePassword>false</ChangePassword>
<CustomDataPageSize>false</CustomDataPageSize>
<CustomMasterDataPageSize>false</CustomMasterDataPageSize>
<DataPageSize>100</DataPageSize>
<Disabled>true</Disabled>
<Displayname>Pål</Displayname>
<Email i:nil="true" />
<EnforcePasswordPolicy>false</EnforcePasswordPolicy>
<EnvironmentIdList xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<GUID i:nil="true" />
<GeoLocation>
    <City i:nil="true" />
    <Country i:nil="true" />
    <CountryCode i:nil="true" />
    <Ip i:nil="true" />
    <Isp i:nil="true" />
    <Lat>0</Lat>
    <Lon>0</Lon>
    <Org i:nil="true" />
    <Query i:nil="true" />
    <Region i:nil="true" />
    <RegionName i:nil="true" />
    <Status i:nil="true" />
    <Timezone i:nil="true" />
    <Zip i:nil="true" />
</GeoLocation>
<GroupIdList xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<HttpLink i:nil="true" />
<JobIdList xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<LastLoggedIn>2015-06-11T19:04:44.6407074+05:30</LastLoggedIn>
<MasterDataPageSize>1000</MasterDataPageSize>
<ModifyImages>false</ModifyImages>
<QualityControl>false</QualityControl>
<QualityControlGroupId i:nil="true" />
<Review>false</Review>
<ReviewGroupId i:nil="true" />
<SecurityToken i:nil="true" />
<ShowTrackerPage>false</ShowTrackerPage>
<StatIdList xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<Username>&lt;new user&gt;</Username>
<Usertype>Power</Usertype>
</UserInfo>

I'm trying to match users that have their accounts disabled.我正在尝试匹配帐户被禁用的用户。 Using the below sql query.使用以下 sql 查询。

select * from [ATC_Config].[dbo].[Users] where [ATC_Config].[dbo].[Users].[Data].value('/UserInfo/Disabled[1]','nvarchar(MAX)') = 'true'

But SSMS is giving me an error Cannot call methods on nvarchar(max) and highlight my column which Data .但是 SSMS 给我一个错误Cannot call methods on nvarchar(max) and highlight my column which Data I tried few suggestions in SO and in MSDN but nothing helped.我在 SO 和 MSDN 中尝试了一些建议,但没有任何帮助。 Can someone show me what am I doing wrong?有人可以告诉我我做错了什么吗?

Because your sample XML contains a default namespace definition you'll need to declare that in your value XQuery or via with xmlnamespaces .因为您的示例 XML 包含默认名称空间定义,您需要在您的value XQuery 中或通过with xmlnamespaces声明它。

Here's how you can do that with value ...以下是您如何利用value来做到这一点......

select *
from dbo.Users
where cast(Data as xml).value(N'
  declare default element namespace "http://schemas.datacontract.org/2004/07/ComponentFramework";
  (/UserInfo/Disabled)[1]',N'nvarchar(max)') = N'true';

Or by using with xmlnamespaces :或者通过with xmlnamespaces使用:

with xmlnamespaces(default N'http://schemas.datacontract.org/2004/07/ComponentFramework')
select *
from dbo.Users
where cast(Data as xml).value(N'(/UserInfo/Disabled)[1]', N'nvarchar(max)') = N'true';

You need to add the namespace, and you need to cast the value to xml .您需要添加命名空间,并且需要将值转换为xml This is easier if you use with because it applies to the whole query.如果使用with会更容易,因为它适用于整个查询。

A slightly more efficient version of @AlwaysLearning's answer is to use exist and /text() @AlwaysLearning 的答案稍微更有效的版本是使用exist/text()

with xmlnamespaces (
    default N'http://schemas.datacontract.org/2004/07/ComponentFramework'
)
select *
from dbo.Users u
where cast(u.Data as xml).exist(N'/UserInfo/Disabled[text() = "true"]') = 1;

db<>fiddle 数据库<>小提琴

I strongly suggest you store the Data column as xml in the first place, as casting is inefficient.我强烈建议您首先将Data列存储为xml ,因为转换效率低下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM