[英]XQuery exists check in select sql query
我有一個帶有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>
在這里,我需要查詢所有具有訪問權限:允許和許可權限:刪除的 UserName值。 為此,我正在使用以下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:Allow和Access:Deny值。
在那種情況下,即使它具有Access:Allow ,我也必須從結果中排除Admin2 。
有人能給我這種情況下的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')
這將給您想要的結果。
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
我認為可以使用純XQuery進行此操作,請稍后再添加。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.