1

以下是我在 SSMS 中的代码。并且工作正常。

但问题是我的@p1='variable1/variable2',我无法得到结果。

谢谢你。

DECLARE @SSRXML xml = '<root>
                        <variable1>
                            <variable2>
                                <variable3>
                                    <name>Alvin</name>
                                    <country>Singapore</country>
                                </variable3>
                            </variable2>
                        </variable1>
                       </root>'

DECLARE @p1 VARCHAR(MAX) =  'variable1'; 

SELECT @SSRXML.query('//root/*[local-name()=sql:variable("@p1")]' )
4

2 回答 2

1

也许这个解决方案有帮助?

DECLARE @p1 VARCHAR(MAX) = 'variable1'
    , @p2 VARCHAR(MAX) = 'variable2';

SELECT @SSRXML.query('//root/*[local-name()=sql:variable("@p1")]/*[local-name()=sql:variable("@p2")]');

目前尚不清楚您所说的“variable1/variable2”是什么意思以及您想要得到什么结果。

如果您知道 @p 变量中的最大节点数,则可以使用此解决方案:

DECLARE @p0 VARCHAR(MAX) = 'variable1/variable2/variable3'
    , @p1 VARCHAR(MAX)
    , @p2 VARCHAR(MAX)
    , @p3 VARCHAR(MAX)
    , @p4 VARCHAR(MAX)
;
SET @p0 = REPLACE (@p0, '/', '.');

SELECT @p1 = ISNULL (PARSENAME(@p0, 1), '')
    , @p2 = ISNULL (PARSENAME(@p0, 2), '')
    , @p3 = ISNULL (PARSENAME(@p0, 3), '')
    , @p4 = ISNULL (PARSENAME(@p0, 4), '')
;

SELECT @SSRXML.query('
if (sql:variable("@p4") != "")
then /root/*[local-name()=sql:variable("@p4")]/*[local-name()=sql:variable("@p3")]/*[local-name()=sql:variable("@p2")]/*[local-name()=sql:variable("@p1")]
else (
    if (sql:variable("@p3") != "")
    then /root/*[local-name()=sql:variable("@p3")]/*[local-name()=sql:variable("@p2")]/*[local-name()=sql:variable("@p1")]
    else (
        if (sql:variable("@p2") != "")
        then /root/*[local-name()=sql:variable("@p2")]/*[local-name()=sql:variable("@p1")]
        else (
            if (sql:variable("@p1") != "")
            then /root/*[local-name()=sql:variable("@p1")]
            else /root
        )
    )
)');
于 2013-09-05T09:12:18.903 回答
1

如果您使用可变路径查询 xml 实例,您可以尝试动态 sql:

DECLARE @SSRXML xml = ...

DECLARE @sql nvarchar(max), @params nvarchar(max), @p1 VARCHAR(MAX)
set @params = '@SSRXML xml';

set @p1 = 'variable1';
set @sql = 'SELECT @SSRXML.query(''root/' + @p1 + ''')'
exec sp_executesql @sql, @params, @SSRXML

set @p1 = 'variable1/variable2';
set @sql = 'SELECT @SSRXML.query(''root/' + @p1 + ''')'
exec sp_executesql @sql, @params, @SSRXML

或者您可以尝试递归遍历 xml 实例元素,然后根据路径选择必要的:

DECLARE @SSRXML xml = ...

declare @p1 varchar(max)
set @p1 = 'variable1/variable2'

;with cte (path, el) as (
    select t.c.value('local-name(.)', 'varchar(max)'), t.c.query('.')
    from @SSRXML.nodes('*') t(c)
    union all
    select cte.path + '/' + t.c.value('local-name(.)', 'varchar(100)'), t.c.query('.')
    from cte
        cross apply el.nodes('*[1]/*') t(c)
)
select el
from cte
where path = 'root/' + @p1
于 2013-09-05T09:19:19.913 回答