【发布时间】:2012-03-21 13:46:55
【问题描述】:
我正在尝试使用带有查询和值函数的 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
注意查询路径是如何“上移”到变量的。我会继续我的调查..
【问题讨论】:
-
据我所知,无法用变量替换整个 XPath 表达式(动态 SQL 除外)。您可以像您一样使用
local-name()将节点名称与变量进行比较。如果您不关心根节点名称是什么,您可以使用//*[local-name() = sql:variable("@xpath")]对匹配@xpath的所有节点进行深度搜索,无论它们位于 XML 中的什么位置。 -
@MikaelEriksson:哦,好吧.. 我不认为双重
//有效,但感谢您的提示。我想我会使用那个或不使用参数.. -
@JeremyCaney 这个问题是8 年前提出的。我当时从事的项目不再是我维护的东西。如果您阅读了建议副本中的答案,那么这些解决方案已在此线程中提到,因此不应成为此处所问问题的答案。
-
@Patrick:我很抱歉;我忘记了自动生成的评论,这在这里完全是荒谬的。我的目标是帮助整合类似的问题,因为现在,有很多关于同一主题的问题。我选择了另一个作为“规范”,因为它更关注核心问题,因此最有可能在未来帮助遇到类似问题的人。
-
啊哈,我没有意识到评论是由于投票结果接近,对此感到抱歉。无论哪种方式,即使问题是相关的,这也是询问如何将查询路径值参数化作为用户输入,而另一个 IIRC 只是如何使用变量。您可以发布带有指向另一个问题的链接的评论,但它会显示在右侧的“链接问题”列表中。
标签: sql sql-server-2008 xquery sqlxml sqlparameter