MSSQL中带有XML查询的存储过程参数给出“参数必须是字符串文字”

时间:2012-03-21 13:46:55

标签: sql sql-server-2008 xquery sqlxml sqlparameters

我正在尝试使用查询和值函数查询带有xml数据列的表。使用常规字符串文字时,一切都还可以,但如果我将它放在存储过程中并尝试使用变量则不起作用。

我想我没有使用正确的数据类型,但经过一些搜索后我无法弄清楚查询函数想要的数据类型。

实施例: 表包含

| Id | xmldata                         |
| 1  | <data><node>value</node></data> |

现在,使用选择查询

select id
from table
where xmldata.query('/data/node').value('.', 'VARCHAR(50)') = 'value'

获取我想要的数据。但是,如果我在存储过程中使用它并使用参数@xpath varchar(100)并将其作为xmldata.query(@xpath)传递给查询方法  我收到了错误

The argument 1 of the xml data type method "query" must be a string literal.

我猜varchar(100)不正确,但是我可以使用哪种数据类型来使MSSQL满意?


更新: 可以,然后呢。显然你不能将参数传递给查询方法“就像那样”,但是可以将sql:variable与local-name结合使用来处理它的一部分。因此,例如,这将起作用

declare @xpath VarChar(100)
set @xpath='node'
select objectData.query('/data/*[local-name() = sql:variable("@xpath")]')
                 .value('.', 'varchar(100)') as xmldata
from table

并在xmldata列中选择值。但是(!)它要求根节点是查询函数中的第一个值。以下工作

declare @xpath VarChar(100)
set @xpath='/data/node'
select objectData.query('*[local-name() = sql:variable("@xpath")]')
                 .value('.', 'varchar(100)') as xmldata
from table

注意查询路径如何“向上移动”到变量。我会继续调查..

1 个答案:

答案 0 :(得分:3)

literalvariable相反。该消息意味着您无法将变量作为第一个参数传递给query

另一种方法是动态SQL:

declare @sql varchar(max)
set @sql = 'select id from table where xmldata.query(''' + @path + 
    ''').value(''.'', ''VARCHAR(50)'') = ''value'''
exec @sql

如您所见,动态SQL不会产生非常易读的代码。我当然会调查替代方案。

编辑:您对local-name()的建议适用于节点名称。

declare @nodename varchar(max)
set @nodename = 'node'
...
where   xmldata.query('//*[local-name()=sql:variable("@nodename")]')
            .value('.', 'varchar(50)') = 'value'

似乎没有相应的路径。