sql - XQuery 存在检查选择 sql 查询

标签 sql sql-server xml xquery sqlxml

我有一个带有 xml 列的 sql 表,其中包含如下 xml 的值

<Security xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Dacl>
    <ACEInformation>
      <UserName>Authenticated Users</UserName>
      <Access>Allow</Access>
      <IsInherited>false</IsInherited>
      <ApplyTo>This object only</ApplyTo>
      <Permission>List Contents</Permission>
      <Permission>Read All Properties</Permission>
      <Permission>Read Permissions</Permission>
    </ACEInformation>
    <ACEInformation>
      <UserName>Administrator</UserName>
      <Access>Allow</Access>
      <IsInherited>false</IsInherited>
      <ApplyTo>This object only</ApplyTo>
      <Permission>Read All Properties</Permission>
      <Permission>Delete</Permission>
    </ACEInformation>
    <ACEInformation>
      <UserName>Admin2</UserName>
      <Access>Allow</Access>
      <IsInherited>false</IsInherited>
      <ApplyTo>This object only</ApplyTo>
      <Permission>Read All Properties</Permission>
      <Permission>Delete</Permission>
    </ACEInformation>
    <ACEInformation>
      <UserName>Admin2</UserName>
      <Access>Deny</Access>
      <IsInherited>false</IsInherited>
      <ApplyTo>This object only</ApplyTo>
      <Permission>Read All Properties</Permission>
      <Permission>Delete</Permission>
    </ACEInformation>
  </Dacl>
</Security>

这里我的需要是,我必须查询具有值访问:允许权限:删除的所有用户名值。为此,我使用以下 XQuery。

select (
       select A.X.value('(UserName/text())[1]', 'nvarchar(max)')+';'
       from T.xmlColumn.nodes('/Security/Dacl/ACEInformation[Access = "Allow" and Permission = "Delete"]') as A(X)
       for xml path(''), type
       ).value('text()[1]', 'nvarchar(max)')
from myTable as T

它返回上述 xml 的值:Administrator;Admin2。查询工作正常..

但是在这里,我期望结果只有一个条目Administrator而不是Admin2.. 因为 Admin2 在两个不同的 ACEInformation 节点中同时具有 Access:AllowAccess:Deny 值。

在这种情况下,我必须从结果中排除 Admin2,即使它具有 Access:Allow

谁能给我这个案例的 xquery 吗?

最佳答案

with cte as (
    select
        A.X.value('(UserName/text())[1]', 'nvarchar(max)') as UserName,
        A.X.value('(Access/text())[1]', 'nvarchar(max)') as Access
    from myTable as T
        outer apply T.xmlColumn.nodes('/Security/Dacl/ACEInformation[Permission = "Delete"]') as A(X)
)
select *
from cte as c1
where
    c1.Access = 'Allow' and
    not exists (select * from cte as c2 where c2.UserName = c1.UserName and c2.Access = 'Deny')

sql fiddle demo

更新

这会给你想要的结果。

with cte as (
    select
        T.ID,
        A.X.value('(UserName/text())[1]', 'nvarchar(max)') as UserName,
        A.X.value('(Access/text())[1]', 'nvarchar(max)') as Access
    from myTable as T
        outer apply T.xmlColumn.nodes('/Security/Dacl/ACEInformation[Permission = "Delete"]') as A(X)
)
select
    T.ID,
    stuff(
        (
            select ',' + c1.UserName
            from cte as c1
            where
              c1.ID = T.ID and c1.Access = 'Allow' and
              not exists (select * from cte as c2 where c2.ID = T.ID and c2.UserName = c1.UserName and c2.Access = 'Deny')
            for xml path(''), type
        ).value('.', 'nvarchar(max)')
    ,1,1,'')
from myTable as T

sql fiddle demo

我认为可以使用纯 XQuery 来完成此操作,稍后尝试添加它。

关于sql - XQuery 存在检查选择 sql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20188220/

相关文章:

javascript - 设计跨平台多内容类型文件格式的最佳方式?

c# - 在没有 SQL Server 的情况下创建 C# 应用程序

java - 在 SQL 语句中使用变量而不是 TableName

sql - Oracle 对非分层数据的分层查询

asp.net - LINQ to SQL 执行时间比 SSMS SQL 长 50 倍

sql-server - 创建分区在 Azure Sql 服务器中不起作用

sql-server - jdbc 的 sql server 登录凭据

xml - 使用 Go 解码 XML : How to find attributes with the same value?

ruby - 如何使用 Nokogiri 拆分 HTML 文档?

sql - PostgreSQL:将表值函数串行应用于一组值和 UNION ALL 结果