【问题标题】:SQL Server XQuery returns an errorSQL Server XQuery 返回错误
【发布时间】:2023-03-26 15:58:02
【问题描述】:

我正在对 SQL Server 2012 中的 XML 数据类型列执行查询。数据示例如下:

<ns:Resume xmlns:ns="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume">
  <ns:Name>
    <ns:Name.Prefix></ns:Name.Prefix>
    <ns:Name.First>Shai</ns:Name.First>
    <ns:Name.Middle></ns:Name.Middle>
    <ns:Name.Last>Bassli</ns:Name.Last>
    <ns:Name.Suffix></ns:Name.Suffix>
  </ns:Name>
  ...
</ns:Resume>

我正在尝试编写一个查询来返回名字。

此查询按预期返回名字列表:

WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume' AS ns)
SELECT [Resume].query('(//ns:Name.First)').value('.[1]', 'nvarchar(100)')
FROM   HumanResources.JobCandidate;

但是,此查询返回错误:

WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume' AS ns)
SELECT [Resume].value('(//ns:Name.First)[1]', 'nvarchar(100)')
FROM   HumanResources.JobCandidate;

错误:

消息 9314,第 16 级,状态 1,第 2 行
XQuery [HumanResources.JobCandidate.Resume.value()]:无法隐式原子化或将“fn:data()”应用于复杂内容元素,在推断类型“(元素(ns{http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume} :Name.First,xs:string) | element(ns{http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume}:Name.First,xs:anyType)) ?'.

我在这里缺少一些基本的理解,但我不确定它是什么。有人可以启发我吗?为什么第二个查询返回错误?

【问题讨论】:

    标签: sql xml sql-server-2012


    【解决方案1】:

    对于 SQL Server 表中的每一行,您的 XPath 表达式可能会导致返回多行。您需要使用CROSS APPLY 并致电.nodes() 来获取您需要的信息:

    WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume' AS ns)
    SELECT 
        JobCandidateID,
        ResNames.value('(ns:Name.First)[1]', 'nvarchar(100)')
    FROM   
        HumanResources.JobCandidate
    CROSS APPLY
        [Resume].nodes('/ns:Resume/ns:Name') AS XTbl(ResNames)
    

    这应该返回表中每一行的所有JobCandidateID 值和Resume XML 列中定义的所有名字。

    如果您可以确定您的 XML 列中只会有一个 &lt;name&gt; 标记,那么您也可以将其缩短为:

    WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume' AS ns)
    SELECT 
        JobCandidateID,
        [Resume].value('(/ns:Resume/ns:Name/ns:Name.First)[1]', 'nvarchar(100)')
    FROM   
        HumanResources.JobCandidate
    

    【讨论】:

    • 我确信你是正确的 marc_s,但在 XML 中这样的事情总是让我陷入循环。你能解释一下为什么已经存在的'..[1]' 不能解决每行可能返回多个项目的问题吗? thnx..
    • @RBarryYoung:是的,我认为[1] 也可以解决问题!但似乎(从抛出的错误消息中)通过搜索//ns:Name.First,SQL Server 中的 XQuery 处理以某种方式假定 XML 模式集合中有一个 Name.First,xs:string 和第二个 Name.First,xs:any(再次:我不知道为什么发生这种情况-我只是偶尔看到它发生)。在这种情况下,XQuery 处理器无法确定 Name.First 元素是什么(什么类型),因此会出错
    • 那么使用'(/ns:Resume/ns:Name/ns:Name.First)[1]' 而不是'(//ns:Name.First)[1]' 会有所不同吗?为什么?
    • @Seiker:因为你对你想要的东西更明确 - 你没有在整个 XML 文档的任何地方要求 任何&lt;name&gt; i> - 您要求一个非常具体、定义非常明确的值
    • sigh 每次我认为我已经弄清楚了 SQL Server XQuery,但我没有。 :-(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多