XML数据类型方法"value"的参数1必须是字符串文字

ekk*_*kis 5 xml t-sql

我读过SO:XML数据类型方法"value"必须是字符串文字,但我的问题有点不同.我在一个变量中有一点xml,我想分开并给出一个路径.最初我试过这个:

declare @x xml
select @x = '....'
select @x.value('(' + @path + ')[1]', 'varchar(max)')
Run Code Online (Sandbox Code Playgroud)

但是,当然,这失败了.然后我找到了sql:variable并尝试了这个:

select @x.value('(sql:variable("@path"))[1]', 'varchar(max)')
Run Code Online (Sandbox Code Playgroud)

但奇怪的是,它返回了@path的值(为什么?).我一直在搞乱它,但不能让它做正确的事情.

想什么?

ekk*_*kis 2

在 Microsoft 网站上wBob的帮助下,我现在得到了一个干净的解决方案。当然,性能是一个问题,因为整个文档将为了单个路径而被映射,但改进留给读者作为建议的可能性:)

if object_id('VMConfigVal') is not null
drop function VMConfigVal
go
create function VMConfigVal(@x xml, @path varchar(max))
returns nvarchar(max)
as
begin
    declare @ret nvarchar(max)

    ;with cte as
    (
    select  value = x.c.value('.', 'varchar(50)')
    ,       path = cast ( null as varchar(max) )
    ,       node = x.c.query('.')
    from    @x.nodes('/*') x(c)
    union all
    select  n.c.value('.', 'varchar(50)')
    ,       isnull( c.path + '/', '/' )
        +       n.c.value('local-name(.)', 'varchar(max)')
    ,       n.c.query('*')
    from    cte c
    cross   apply c.node.nodes('*') n(c)
    )
    select @ret = value from cte where path = @path
    return @ret
    end
go
Run Code Online (Sandbox Code Playgroud)

所以我现在可以做类似的事情:

select dbo.VMConfigVal(MyXMLConfig, '/hardware/devices/IDE/ChannelCount')
from someTable
Run Code Online (Sandbox Code Playgroud)

甜的!