Sql server 如何构建XQuerys以基于特定标记和属性的存在包括/排除行?

Sql server 如何构建XQuerys以基于特定标记和属性的存在包括/排除行?,sql-server,xml,xpath,conditional,xquery,Sql Server,Xml,Xpath,Conditional,Xquery,我有一个审计/日志系统,它使用原始XML表示应用程序执行的操作。我希望通过在应用程序的SQL Server数据库的表中使用XML列来大大改进这个系统 表中的每一行将包含一个日志条目,每个条目应包含一个或多个标记,用于以语义方式描述操作,允许我以符合应用程序审核需求的方式进行搜索,例如: <updateInvoice id="5" userId="7" /><fieldUpdate name="InvoiceDate" /><invoice /><upda

我有一个审计/日志系统,它使用原始XML表示应用程序执行的操作。我希望通过在应用程序的SQL Server数据库的表中使用XML列来大大改进这个系统

表中的每一行将包含一个日志条目,每个条目应包含一个或多个标记,用于以语义方式描述操作,允许我以符合应用程序审核需求的方式进行搜索,例如:

<updateInvoice id="5" userId="7" /><fieldUpdate name="InvoiceDate" /><invoice /><update />

<deleteInvoice id="5" userId="6" /><invoice /><delete />
我的目标是接受其中的一组,并生成一个查询,返回与任何单个包含筛选器匹配的任何行,而不与任何单个排除筛选器匹配


我应该也可以将这个布尔逻辑编码到结果XPath本身中,还是在输出查询中使用多个SELECT语句?我是XQuery新手,非常感谢您的帮助。谢谢

我不确定这是否是您想要的,但是要在XML方法中过滤节点,可以使用括号
[
]
。例如,要选择元素
foo
,但只过滤那些具有属性
bar
的元素,您可以使用类似于
/foo[@bar]
的XPath。如果您想要那些属性为
@bar
且值为5的对象,可以使用
/foo[@bar=5]
。如果要选择具有子元素
bar
的元素
foo
,请使用
/foo[bar]

declare @t table (x xml);
insert into @t (x) values 
(N'<foo bar="abc"/>');
insert into @t (x) values 
(N'<foo bar="5"/>');
insert into @t (x) values 
(N'<foo id="1"><bar id="2"/></foo>');
select * from @t;

select c.value(N'@bar', N'varchar(max)') 
from @t cross apply x.nodes(N'/foo[@bar]') t(c)

select c.value(N'@bar', N'varchar(max)') 
from @t cross apply x.nodes(N'/foo[@bar=5]') t(c)
select c.value(N'@id', N'int') 
from @t cross apply x.nodes(N'/foo[bar]') t(c)
declare@t表(xxml);
在@t(x)值中插入
(N“);
在@t(x)值中插入
(N“);
在@t(x)值中插入
(N“);
从@t中选择*;
选择c.value(N'@bar',N'varchar(max)')
从@t交叉应用x.nodes(N'/foo[@bar]')t(c)
选择c.value(N'@bar',N'varchar(max)')
从@t交叉应用x.nodes(N'/foo[@bar=5]')t(c)
选择c.value(N'@id',N'int')
从@t交叉应用x.nodes(N'/foo[bar]')t(c)

我试图在您的帖子中展示XML代码片段上的示例,但这些示例太无结构,无法成为有用的示例。

这似乎是一个好的开始。我必须多读一点关于交叉应用的内容,但似乎我会像我所怀疑的那样在查询的关系部分中使用布尔逻辑。谢谢你的帮助。
declare @t table (x xml);
insert into @t (x) values 
(N'<foo bar="abc"/>');
insert into @t (x) values 
(N'<foo bar="5"/>');
insert into @t (x) values 
(N'<foo id="1"><bar id="2"/></foo>');
select * from @t;

select c.value(N'@bar', N'varchar(max)') 
from @t cross apply x.nodes(N'/foo[@bar]') t(c)

select c.value(N'@bar', N'varchar(max)') 
from @t cross apply x.nodes(N'/foo[@bar=5]') t(c)
select c.value(N'@id', N'int') 
from @t cross apply x.nodes(N'/foo[bar]') t(c)