33

我有一个存储为文本的类型化 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()' 需要一个单例(或空序列),找到类型为 'xdt:untypedAtomic *' 的操作数

我用谷歌搜索的内容说 XPATH/XQUERY 需要在括号内和/或需要“[1]” - 两者都没有工作。xml 中只有一个 student-id 元素,但我猜架构允许更多?

此外,我想检索许多元素值 - 有没有办法声明命名空间一次而不是每个方法调用?

4

3 回答 3

70

你需要使用这个:

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]以简单地选择该序列的第一个值。

于 2009-08-19T19:37:52.860 回答
8

我相信这也可能这样做:

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
于 2011-08-22T18:00:36.490 回答
3

对于那些对性能感兴趣的人,我运行了一个查询来比较这些方法,第一个选项与 "() 并添加 [1]" 比 ".query('strFranchise').value('.',... )”。

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

于 2015-05-13T06:37:46.573 回答