Come restituire un null da un tag XML vuoto nel server SQL utilizzando solo Xpath?


8

Ho un'applicazione che memorizza vari punti dati definiti dall'utente su un record in una colonna XML. Non ho alcun controllo su come questi sono memorizzati o aggiornati.

Quando eseguo una query su una colonna, può restituire 1 di 3 valori:

  1. Il valore
  2. Nullo
  3. Una stringa vuota

$ 64 domanda Vorrei restituire quelle stringhe vuote come null utilizzando xpath.

Ho trovato molte risposte su come restituire il null come una puntura vuota, ma nulla in questo modo.

Finiscono in questo modo quando qualcuno ha eliminato il valore e invece di eliminare il tag lo cancella in un <value />tag. I valori null si verificano quando il valore non è mai stato impostato. Non hanno incluso xsi: nil.

L'ho fatto con un'istruzione case:

    select
    so.SalesOrderId,
    Case
        when sopc.value('(Value)[1]','smalldatetime') IS null then Null
        when sopc.value('(Value)[1]','smalldatetime') ='' then Null
        Else sopc.value('(Value)[1]','smalldatetime')
    End as sopc
    From
    SalesOrders so
    Outer apply so.CustomColumns.nodes('/CustomColumnsCollection/CustomColumn[Name="ProjCompleted"]') sopc(sopc)

ma questo sembra inefficiente e questa non è l'unica colonna, quindi rende il codice lungo e più difficile da mantenere.

Modifica per includere dati di esempio

SalesOrderId    CustomColumns
SO 1            "<CustomColumnsCollection>
                   <CustomColumn>
                     <Name>ProjCompleted</Name>
                     <DataType>1</DataType>
                     <Value />
                   </CustomColumn>
                 </CustomColumnsCollection>"
SO 2           "<CustomColumnsCollection>
                  <CustomColumn>
                     <Name>ProjCompleted</Name>
                     <DataType>1</DataType>
                     <Value>'2017-11-21'</Value>
                  </CustomColumn>
                </CustomColumnsCollection>"
SO 3           "<CustomColumnsCollection>
                </CustomColumnsCollection>"

**Output**
Current      Desired
''           null
2017-11-21   2017-11-21
null         null

Grazie in anticipo.


Grazie Scott - come vedi è la mia prima domanda, esiste un formato preferito?
TimNewman,

Aggiorna semplicemente la tua domanda con un blocco di codice (simile al codice che hai già pubblicato) che ha l'esempio XML e includi un altro blocco di codice dei risultati previsti. Vedi Come creare un esempio minimo, completo e verificabile
Scott Hodgin,

Grazie - Ho accettato una risposta ma modificherò comunque la domanda per renderla utile a chiunque lo trovi.
TimNewman,

Risposte:


11

Specifica il text()nodo all'interno Valuedell'elemento. Quel nodo manca quando hai un tag vuoto.

Prova questo:

declare @X xml;
set @X = '<Value/>';

select @X.value('(Value/text())[1]', 'smalldatetime'),
       @X.value('(Value/text())[1]', 'varchar(max)'),
       @X.value('(Value/text())[1]', 'int'),
       @X.value('(Value)[1]', 'smalldatetime'),
       @X.value('(Value)[1]', 'varchar(max)'),
       @X.value('(Value)[1]', 'int');

Risultato:

------------------- ---------- ----------- ----------------------- ---------- -----------
NULL                NULL       NULL        1900-01-01 00:00:00                0

È una buona cosa in generale specificare sempre il text()nodo. Il piano di query è più semplice ed efficiente.

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.