2016-01-21 15 views
10

In Postgres:La concatenazione di stringhe con null sembra annullare l'intera stringa: è il comportamento desiderato in Postgres?

select 'test' || null returns null 

mi aspettavo che sarebbe altrimenti restituisce 'test'.

È questo comportamento desiderato? Sembra strano che concatenazione di stringhe con un valore nullo vanificherebbe l'intera stringa ...

riferimento alla documentazione PG: http://www.postgresql.org/docs/9.1/static/functions-string.html

"Nota: Prima di PostgreSQL 8.3, queste funzioni sarebbe silenziosamente accettare i valori di diversi non- anche i tipi di dati stringa, a causa della presenza di coercizioni implicite da quei tipi di dati al testo.Queste coercizioni sono state rimosse perché spesso causavano comportamenti sorprendenti.Tuttavia, l'operatore di concatenazione delle stringhe (||) accetta ancora input non stringa, quindi tanto che almeno un input è di tipo stringa, come mostrato nella Tabella 9-6. In altri casi, inserisci una coercizione esplicita al testo se hai bisogno di duplicare il comportamento precedente. "

Dato che, con la loro funzione di stringa concat esempio:

concat (str "qualsiasi" [, str "qualsiasi" [...]]) testo concatenare tutti gli argomenti. Gli argomenti NULL vengono ignorati. concat ('abcde', 2, NULL, 22) >> abcde222

Dovrei solo abituarmi a questo comportamento con '||' concatenazione o è qualcosa che dovrebbe essere risolto?

+4

E 'non solo "desiderato", è così che è specificato nello standard SQL. –

+0

@a_horse_with_no_name - che è lo standard SQL è tutto ciò che avevo davvero bisogno di sapere - il tuo commento dovrebbe essere la risposta. Sembra tuttavia non intuitivo. Mi ha sfidato a dare un'occhiata a come le altre lingue gestiscono quel caso. C# sembra offrire l'intuitivo, trattando il null come una stringa di lunghezza zero. Javascript e Java concatenano "null" alla stringa (sheesh). – Reinsbrain

risposta

6

Sì, è il comportamento desiderato.

Ecco un esempio in cui è molto utile. Supponiamo di avere un tavolo per le persone e i campi title, firstname, nameaffix e lastname. Per costruire un nome completo puoi semplicemente farlo.

Senza questo strano comportamento sarebbe abbastanza conveniente mettere gli spazi nei punti giusti a seconda che un campo sia nullo o meno. Assumendo un nome e un cognome obbligatori è coperta qualsiasi combinazione di titolo e apposizione del nome.

+11

L'uso di 'concat_ws (',', titolo, nome, nameaffix, lastname)' è ancora più semplice –

+1

@a_horse_with_no_name Oh, fantastico! 'Inventato' l'esempio in 8.4 e non ho mai cercato una funzione da allora. Funziona dal 9.1, cioè. Grazie! – MyBrainHurts

10

Non è un bug e non è "strano".

Lo standard SQL richiede qualsiasi espressione che implichi le rese nullnull. Questo non è limitato alla concatenazione di stringhe, ma si applica anche ai calcoli, ad esempio: 42 * null restituisce null.

Questo vale anche per i confronti: 42 > null rese null. Quindi il paragone non è né vero né falso. Anche se in realtà questo ha l'effetto di "falso", ma più perché è "non vero", piuttosto che falso. Ma negare una tale espressione produce di nuovo null, non "vero".

Perché null è così speciale, l'unico modo per verificare se qualcosa è nullo è quello di utilizzare l'operatore IS NULL o IS NOT NULL.x is null restituisce true o false, non restituisce mai null, quindi espressioni utilizzando is null o is not null operatore mai restituisce null - quindi questa è un'eccezione alla mia dichiarazione precedente (grazie a Jonathan per averlo indicato).


altro - forse sorprendente - infatti circa null valori è il modo in cui sono gestite da funzioni di aggregazione. Mentre l'espressione 4 + 5 + null restituisce null, il valore sum() su quelli (colonna) restituisce 9, poiché gli aggregati ignorano i valorinull.

base alla tabella seguente:

col1 
-------- 
     1 
     2 
     3 
    null 

sum(col1) torneranno 6, e avg(col1) tornerà 2 (somma = 6, il numero di elementi aggiunto: 3)

+0

L'uso di _any_ è un po 'eccessivo, anche se non di molto. Tra le eccezioni ci sono 'x IS NULL' e' x IS NOT NULL' e i loro parenti. E il punto chiave su 'x> 42' quando' x' è nullo è che la riga non è selezionata, ma non è selezionata quando si filtra su 'x <42' - per selezionare tutte le righe, è necessario 'x> 42 O x <42 O x È NULL'. –

+0

@JonathanLeffler: regarging '>' vs. '<' questo è quello che volevo trasmettere quando ho menzionato che questo non è "falso", ma non è vero. Riguardo alla "qualsiasi espressione". Esiste un termine che distingue tra 'x> null' e' x is not null'? Sento che sono qualcosa di simile, ma non posso nominarlo;) –

1

citazione dalla documentazione

Concatena tutti gli argomenti. Gli argomenti NULL vengono ignorati.

Esempio

concat('abcde', 2, NULL, 22) 

Returns

abcde222 

Scopri di più su Documentation