在SQL Server 2008中,我希望在子元素名称为动态的情况下识别不包含给定子元素的元素。在此XML中,所有三个 li 元素都包含 F1 和 F2 子元素,第二个和第三个 li &#39 ; s不包含 edge 元素。如果事先知道 edge 元素的名称,我可以找到没有 edge 子元素的 li ,请参阅下面存在查询,它应该返回1。
declare @x xml = '<data>
<li>
<F1>ellipse</F1>
<F2 />
<edges/>
</li>
<li>
<F1>triangle</F1>
<F2>3</F2>
</li>
<li>
<F1>square</F1>
<F2>4</F2>
</li>
</data>';
select @x.exist('/data/li[not(F1)]') -- returns 0, there is no li without an F1 (OK)
select @x.exist('/data/li[not(edges)]') -- returns 1, there is an li without edges (OK)
但如果事先不知道 edge 值,我该如何使用SQL变量指定它?我想编写如下代码:
declare @ChildElement varchar(100) = 'edges';
select @x.exist('/data/li[not(sql:variable("@ChildElement"))]') -- not allowed
但是SQL Server中的sql:variable在此上下文中无效。我也尝试过使用local-name():
select @x.exist('/data/li[not(local-name()=sql:variable("ChildElement"))]') -- always returns 1
但它总是返回1.我认为因为总有一个 li ,其子元素不是 F1 ,并且始终有 li < / strong>包含不是边的子元素。如果 edge 在SQL变量中,如何只识别 li 而没有 edge 子元素? BTW我正在使用SQL Server 2008,虽然我认为这适用于2005年以后的所有SQL Server版本。
答案 0 :(得分:3)
我猜测你的第一种方法不起作用,因为变量被字符串“替换”(我不知道SQL Server的XQuery功能是否足以解释详细情况)
第二种方法是查询所有li元素,其中li元素的local-name()
(当前上下文!)等于SQL变量 - 可能不是你想要做的。相反,尝试
select @x.exist('/data/li[not(./*[local-name()=sql:variable("@ChildElement")])]')
代替测试所有孩子。