如何选择名称等于变量值的属性?

时间:2017-08-31 22:23:37

标签: sql-server xml xpath xquery

以下SQL Server(2008版)代码

declare @x xml = '
<PKs>
  <Column Name="a" />
  <Column Name="b" />
</PKs>
<Selected>
  <row a="444010" b="2" />
  <row a="444012" b="3" />
  <row a="444003" b="2" />
  <row a="444009" b="4" />
  <row a="444002" b="3" />
  <row a="444005" b="1" />
</Selected>'

declare @s nvarchar(max) = @x.query('
for $r in /Selected/row 
return <s>({
    for $k in /PKs/Column 
    return <s>{data($k/@Name)} = {data($r[.=$k/@Name])} and </s>}1=1) or
    </s>').value('.', 'nvarchar(max)')
print @s

返回

(a =  and b =  and 1=1) or
    (a =  and b =  and 1=1) or
    (a =  and b =  and 1=1) or
    (a =  and b =  and 1=1) or
    (a =  and b =  and 1=1) or
    (a =  and b =  and 1=1) or

预期结果是

(a = 444010 and b = 2 and 1=1) or
    (a = 444012 and b = 3 and 1=1) or
    (a = 444003 and b = 2 and 1=1) or
    (a = 444009 and b = 4 and 1=1) or
    (a = 444002 and b = 3 and 1=1) or
    (a = 444005 and b = 1 and 1=1) or

问题在于行return <s>{data($k/@Name)} = {data($r[.=$k/@Name])} and </s>}1=1) or,我需要选择$r/@($k/@Name)(具有语法错误)而不是$r[.=$k/@Name]的值。

1 个答案:

答案 0 :(得分:2)

动态计算属性名称并不是真正的惯用XQuery,但可以通过使用@*枚举所有属性然后通过使用fn:local-name()访问其名称来手动过滤所需属性来完成:

for $r in /Selected/row 
return <s>({
    for $k in /PKs/Column
    let $col := $r/@*[local-name()=$k/@Name]
    return <s>{data($k/@Name)} = {data($col)} and </s>}1=1) or
    </s>