代码之家  ›  专栏  ›  技术社区  ›  OMG Ponies

xml query()有效,value()需要找到singleton xdt:untypedatomic

  •  32
  • OMG Ponies  · 技术社区  · 15 年前

    我有一个作为文本存储的类型化XML文档。因此,我使用通用表表达式将数据类型转换为XML,以便能够使用XML方法:

    WITH xoutput AS (
      SELECT CONVERT(xml, t.requestpayload) 'requestpayload'
        FROM TABLE t
       WHERE t.methodid = 1)
    SELECT x.requestpayload.query('declare namespace s="http://blah.ca/api";/s:validate-student-request/s:student-id') as studentid
      FROM xoutput x
    

    查询工作,返回元素给我。但我只对价值感兴趣:

    WITH xoutput AS (
      SELECT CONVERT(xml, t.requestpayload) 'requestpayload'
        FROM TABLE t
       WHERE t.methodid = 1)
    SELECT x.requestpayload.value('declare namespace s="http://blah.ca/api";/s:validate-student-request/s:student-id', 'int') as studentid
      FROM xoutput x
    

    这给了我以下错误:

    “value()”需要一个singleton(或空序列),找到“xdt:untypedatomic*类型的操作数

    我在google上说,xpath/xquery需要在括号内和/或需要“[1]”—两者都不起作用。XML中只有一个student id元素,尽管我猜这个模式允许更多的元素?

    此外,还有许多我想要检索的元素值——有没有一种方法可以声明一次命名空间而不是每个方法调用?

    3 回复  |  直到 9 年前
        1
  •  66
  •   canon    10 年前

    你需要使用这个:

    SELECT 
            x.requestpayload.value('declare namespace s="http://blah.ca/api";
                (/s:validate-student-request/s:student-id)[1]', 'int') 
        AS
            studentid
        FROM 
            xoutput x

    你需要输入你的xpath ( ... ) 添加一个 [1] 只需选择该序列的第一个值。

        2
  •  8
  •   marc_s HarisH Sharma    13 年前

    我相信这也可以做到:

    SELECT 
       x.requestpayload.query('declare namespace s="http://blah.ca/api";
                               /s:validate-student-request/s:student-id').value('.', 'int') 
      as studentid
    FROM xoutput x
    
        3
  •  3
  •   David Coster    9 年前

    对于那些对性能感兴趣的人,我运行了一个查询来比较这些方法,第一个选项用“()和add a[1]”比“.query('strfranchise').value('.',…)”快得多。

    在相同的数据上逐个运行时,执行计划的差异为15%到85%。所以()[1]快了5倍多!执行计划大不相同。