问题
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