В SQL Server 2008 я хочу идентифицировать элементы, которые не содержат заданный дочерний элемент в случае, когда имя дочернего элемента является динамическим. В этом XML все три элемента li содержат дочерние элементы F1 и F2, а второй и третий элементы li do не содержат элемент edges. Я могу найти элементы li без дочерних элементов edges, если заранее известно имя элемента edges — см. exist< /em> запрос ниже, который возвращает 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)
Но если значение edges заранее неизвестно, как указать его с помощью переменной SQL? Я хотел бы закодировать что-то вроде следующего:
declare @ChildElement varchar(100) = 'edges';
select @x.exist('/data/li[not(sql:variable("@ChildElement"))]') -- not allowed
но sql:variable недействительна в этом контексте в SQL Server. Я также пробовал комбинации с использованием local-name():
select @x.exist('/data/li[not(local-name()=sql:variable("ChildElement"))]') -- always returns 1
но он всегда возвращает 1. Я думаю, потому что всегда есть li с дочерним элементом, который не является F1, и всегда есть li с дочерним элементом, который не является ребрами. Как я могу идентифицировать только li без подэлемента edges, если edges находится в переменной SQL? Кстати, я использую SQL Server 2008, хотя я думаю, что это относится ко всем версиям SQL Server с 2005 года.