在xpath中使用变量来获取xquery(value)

时间:2016-09-08 21:48:20

标签: sql-server xpath xquery

{
    "aps" : {
        "alert" : "You got your emails.",
        "badge" : 9,
        "sound" : "bingbong.aiff"
    },
    "acme1" : "bar",
    "acme2" : 42
}

我正在尝试使用此语法但不起作用

我想在xquery(value)

中使用带有xpath的变量
set @xml = '
<body>
    <Record>
        <A>a</A>
        <B>b</B>
        <C>c</C>
    </Record>
    <Record>
        <A>d</A>
        <B>e</B>
        <C>f</C>
    </Record>
    <Record>
        <A>g</A>
        <B>h</B>
        <C>i</C>
    </Record>
</body>
'

出了什么问题?

1 个答案:

答案 0 :(得分:0)

SQL Server XML中没有动态路径功能。你的选择是

将路径拆分为单独的组件,例如:

declare @xml xml;

declare @Node1 sysname = N'Record', @Node2 sysname = N'A', @Node1Number int = 2;

set @xml = '<body>
    <Record>
        <A>a</A>
        <B>b</B>
        <C>c</C>
    </Record>
    <Record>
        <A>d</A>
        <B>e</B>
        <C>f</C>
    </Record>
    <Record>
        <A>g</A>
        <B>h</B>
        <C>i</C>
    </Record>
</body>';

select @xml.value('(/body/
*[local-name() = sql:variable("@Node1") and position() = sql:variable("@Node1Number")]/
*[local-name() = sql:variable("@Node2")]/
text())[1]', 'nvarchar(50)');

但是,如果您的路径是整个字符串,并且您不想编写解析器,则唯一的选择是动态SQL:

declare @Path nvarchar(max) = N'/body/Record[2]/A', @Sql nvarchar(max);

set @Sql = N'select t.c.value(''./text()[1]'', ''nvarchar(50)'') from @xml.nodes('
+ quotename(@Path, '''')
+ ') t(c);'

exec sys.sp_executesql @Sql, N'@xml xml', @xml = @xml;

就个人而言,我不喜欢他们中的任何一个,并建议重新考虑整个任务。有可能,比在数据库端动态查询XML有更好的解决方案。