Long path xquery in SQL Server

纵然是瞬间 提交于 2020-01-16 05:26:06

问题


Below is my code in SSMS. and is working fine.

But problem is my @p1='variable1/variable2', and I am not able to get the result.

Thank you.

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")]' )

回答1:


If you query xml instance with variable path, you may try dynamic 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

Or you may try recursively walk xml instance elements and then select necessary based on path:

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



回答2:


Maybe this solution helps?

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

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

It is not clear what you mean by 'variable1/variable2' and what result you want to get.

If you know maximum number of nodes in @p variable you can use this solution:

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
        )
    )
)');


来源:https://stackoverflow.com/questions/18631868/long-path-xquery-in-sql-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!