我有一个相当大的结构化XML收据,我要将其解析为关系数据库。在不同的级别上有一些相同的结构,因此使用相同的SQL语句解析它们是非常好的。像:
DECLARE @XMLPath varchar(127)
SET @XMLPath = 'atag/btag/item'
INSERT INTO XMLReadItems
SELECT ci.InvoiceID,
T.c.value('productname[1]', 'varchar(63)') AS InvoiceTarget,
T.c.value('unit[1]', 'varchar(15)') AS Unit,
FROM @XMLItems ci CROSS APPLY XMLCol.nodes(*[local-name()=sql:variable("@XMLPath")]') T(c)
@XMLPath
可以是变量的字符串,也可以是表格中的字段(使用sql:column()
怎么办?)。但是他们中的任何一个我都无法工作。
我只能在XMLCol.nodes()
中使用静态字符串。
答案 0 :(得分:2)
您无法动态构造XQuery参数,因为它仅限于文字字符串。请参阅MSDN关于nodes()
XML方法的参数的说明:
的XQuery
是字符串文字,XQuery表达式。如果查询表达式构造节点,则这些构造的节点将在结果行集中公开。如果查询表达式导致空序列,则行集将为空。如果查询表达式静态地导致包含原子值而不是节点的序列,则会引发静态错误。
强制将SQL变量传递给nodes()
方法会触发错误:
XML数据类型方法的参数1"节点"必须是字符串文字。
您尝试实施的技巧仅适用于动态匹配元素,而不是动态构建整个XPath 。例如,以下内容应该可以正常处理item
元素:
SET @elementName = 'item'
SELECT .....
FROM @XMLItems ci
CROSS APPLY XMLCol.nodes('//*[local-name()=sql:variable("@elementName")]') T(c)
最终,除非您想进一步动态构建整个查询,否则我无法解决此限制(请参阅:sp_executesql
)。