[英]'local-name()' requires a singleton (or empty sequence) T-SQL Xquery
这是这两个问题的变体/组合,但我想我已经按照他们的描述做了:
有没有办法在 SQL Server 2016 T-SQL 查询中获取节点的名称?
我想做这个:
select
trcid,
trcXML.value(
'local-name(//*[local-name()="after"][1]/*[1])',
'varchar(32)'
) as XmlTableName,
trcXml,
trcGUID,
trcCorrID
from trace
order by trcId desc
我在层次结构中的每个项目之后都明确包含了[1]
。
错误:XQuery [trace.trcXML.value()]: 'local-name()' 需要单例(或空序列),找到类型为
'element(*,xdt:untyped) *'
样本数据:
<s1:DB2Request xmlns:s1="XYZDB2">
<s1:sync>
<s1:after identityInsert="false">
<s1:PG204AT5>
<s1:ISA06>1975111</s1:ISA06>
etc...
</s1:PG204AT5>
</s1:after>
</s1:sync>
</s1:DB2Request>
我想要位于“after”和 ISA06 元素之间的表名(这是一个 BizTalk“update-gram”),在本例中为:PG204AT5。
在 xpathtester.com 中测试: local-name(//*[local-name()="after"][1]/* [1])
- 出于某种原因,当我保存它时,XPATH 被更改: http:// www.xpathtester.com/xpath/2bd602d8fc7aee0484de14bf93f71ef2
另一组括号根据需要为您提供单例:
DECLARE @t TABLE(s XML);
INSERT INTO @t(s)VALUES(N'<s1:DB2Request xmlns:s1="XYZDB2">
<s1:sync>
<s1:after identityInsert="false">
<s1:PG204AT5>
<s1:ISA06>1975111</s1:ISA06>
<somethingsomething/>
</s1:PG204AT5>
</s1:after>
</s1:sync>
</s1:DB2Request>');
select
s.value(
'local-name((//*[local-name()="after"][1]/*)[1])',
'varchar(32)'
) as XmlTableName
from @t;
结果是:
XmlTableName
PG204AT5
请记住,与大多数 XQuery 实现不同,SQL Server 引擎执行“悲观静态类型化”——它假设如果事情可能出错,他们就会出错。
表达式//*[local-name()="after"][1]/* [1]
能够返回多个元素 - 例如它会使用这个输入返回
<x>
<y>
<after>
<z/>
</after>
</y>
<y>
<after>
<z/>
</after>
</y>
</x>
因此 XQuery 编译器推断出静态类型的 element()*,这不符合要求。
简单地执行(//*[local-name()="after"]/*)[1]
可能就足够了。
就我个人而言,我一直认为悲观的静态类型是一个非常糟糕的设计选择,但包括 Microsoft 在内的一些早期 XQuery 实现者非常热衷于它。
或者通过明确询问<s1:after>
元素的第一个子节点名称来更简单的解决方案。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE(xmldata XML);
INSERT INTO @tbl(xmldata)
VALUES(N'<s1:DB2Request xmlns:s1="XYZDB2">
<s1:sync>
<s1:after identityInsert="false">
<s1:PG204AT5>
<s1:ISA06>1975111</s1:ISA06>
<somethingsomething/>
</s1:PG204AT5>
</s1:after>
</s1:sync>
</s1:DB2Request>');
-- DDL and sample data population, end
;WITH XMLNAMESPACES (DEFAULT 'XYZDB2')
SELECT xmldata.value('local-name((/DB2Request/sync/after/child::node())[1])','VARCHAR(50)') as XmlTableName
FROM @tbl;
输出
+--------------+
| XmlTableName |
+--------------+
| PG204AT5 |
+--------------+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.