2009-08-19 12 views
31

Mam zapisany dokument xml zapisany jako tekst. Więc używam przekonwertować typ danych XML za pomocą wyrażenia tabelowego aby móc korzystać z metod XML:Funkcja zapytania XML() działa, wartość() wymaga pojedynczego znalezienia xdt: untypedAtomic

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 

Zapytanie działa, wracając do mnie element. Ale jestem zainteresowany tylko wartości:

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 

To daje mi następujący błąd:

'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'

Co mam google mówi, że XPATH/XQuery musi być wewnątrz nawiasu i/lub potrzeby "[1]" - żadna nie zadziałała. W pliku xml znajduje się tylko jeden element identyfikatora ucznia, choć sądzę, że schemat pozwala na więcej?

Dodatkowo istnieje wiele wartości elementów, które chciałbym odzyskać - czy istnieje sposób na zadeklarowanie przestrzeni nazw zamiast wywołania metody?

Odpowiedz

62

Trzeba to wykorzystać:

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

Trzeba umieścić swój XPath w (...) i dodaj [1] po prostu wybrać pierwszą wartość tej sekwencji.

7

wierzę Może to również zrobić:

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

Dla zainteresowanych wydajności Pobiegłem zapytanie do porównania tych podejść i pierwszą opcję z „() i dodać [1]” była znacznie szybciej niż ".query (" strFranchise "). wartość (". ", ...)".

Różnica w planie wykonania wynosiła od 15% do 85% przy uruchamianiu jednego po drugim na tych samych danych. Więc() [1] jest ponad 5 razy szybszy! Plan wykonania jest znacznie inny.

+0

Jak rozumiem, "[1]" zwraca tylko pierwszy wynik, podczas gdy '.value (". "Zwraca wszystkie wyniki. –

Powiązane problemy