2009-08-19 7 views
31

Ho un documento xml digitato memorizzato come testo. Quindi io uso convertire il tipo di dati in XML utilizzando un'espressione di tabella comune, al fine di essere in grado di utilizzare i metodi XML:XML query() funziona, value() richiede singleton trovato 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 

query funziona, tornando a me l'elemento. Ma mi interessa solo il valore:

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 

Questo mi dà il seguente errore:

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

Cosa Googled dice che il XPATH/XQuery ha bisogno di essere all'interno di parentesi e/o ha bisogno di "[1]" - nessuno dei due ha funzionato. C'è solo un elemento id studente-in xml, anche se immagino che lo schema ne consenta di più?

Inoltre, ci sono numerosi valori di elementi che vorrei recuperare: esiste un modo per dichiarare lo spazio dei nomi una volta piuttosto che per una chiamata di metodo?

risposta

62

è necessario utilizzare questo:

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

è necessario mettere la vostra XPath in (...) e aggiungere un [1] per selezionare semplicemente il primo valore di tale sequenza.

7

Credo anche questo potrebbe fare:

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

Per coloro che sono interessati in termini di prestazioni ho eseguito una query per confrontare questi approcci e la prima opzione con "() e aggiungere un [1]" era molto più veloce di quanto ".query ('strFranchise'). value ('', ...)".

La differenza nel piano di esecuzione era compresa tra il 15% e l'85% quando si eseguivano uno dopo l'altro sugli stessi dati. Quindi() [1] è oltre 5 volte più veloce! Il piano di esecuzione è molto diverso.

+0

Come ho capito '[1]' restituisce solo il primo risultato mentre '.value ('.'' Restituisce tutti i risultati. –

Problemi correlati