Подтвердить что ты не робот

XML-запрос() работает, значение() требует, чтобы singleton нашел xdt: untypedAtomic

У меня есть типизированный XML-документ, сохраненный как текст. Поэтому я использую CONVERT для типа данных для xml с помощью выражения Common Table Expression, чтобы иметь возможность использовать методы 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 *'

То, что я искал в google, говорит, что XPATH/XQUERY должен быть внутри скобок и/или нужен "[1]" - ни одна из них не работала. Там только один элемент student-id в xml, хотя я предполагаю, что схема позволяет больше?

Кроме того, есть множество значений элементов, которые я хотел бы получить - есть ли способ объявить пространство имен один раз, а не вызов метода?

4b9b3361

Ответ 1

Вам нужно использовать это:

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

Я считаю, что это также может сделать:

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

Для тех, кто интересуется производительностью, я выполнил запрос для сравнения этих подходов, и первый вариант с "() и добавлением [1]" был намного быстрее, чем ".query('strFranchise'). value ('.',...)".

Разница в плане исполнения составляла от 15% до 85% при однократном запуске на одних и тех же данных. So() [1] более чем в 5 раз быстрее! План выполнения сильно отличается.