Documentazione di PostgreSQL 9.0 > Il linguaggio SQL > Sintassi SQL > Espressioni di valore
PrecedenteSintassi SQLChiamare funzioniSuccessivo

4.2. Espressioni di valore

Le espressioni di valore sono usate in contesti vari, come nell'elenco di destinazioni del comando SELECT, nuovi valori per colonne nell'INSERT o UPDATE, o in condizioni di ricerca di diversi comandi. Il risultato di un'espressione di valore a volte è chiamato scalare, per distinguerlo dal risultato di un'espressione di tabella (che è una tabella). Le espressioni di valore sono anche chiamate espressioni scalari (o anche semplicemente espressioni). La sintassi delle espressioni permette il calcolo di valori da parti primitive usando operazioni aritmetiche, logiche, su insiemi, ed altre.

Un valore di espressione è uno dei seguenti:

  • Un valore costante o letterale

  • Un riferimento di colonna

  • Un riferimento posizionale a un parametro, nel corpo di una definizione di funzione o istruzione preparata

  • Un'espressione sottoscritta

  • Un'espressione di selezione di campo

  • Un'invocazione di operatore

  • Una chiamata a funzione

  • Un'espressione aggregata

  • Una chiamata a una funzione finestra

  • Una conversione di tipo

  • Una sottoquery scalare

  • Un costruttore di array

  • Un costruttore di riga

  • Un'altra espressione di valore in parentesi (usata per raggrupare sottoespressioni e sovrascrivere la precedenza delle )

In aggiunta a questo elenco, ci sono altri construttori che possono essere classificati come un'espressione ma non seguono nessuna regola generale di sintassi. Queste generalmente hanno la semantica fi una funzione o operatore e sono spiegate nella sezione apposita in Capitolo 9, Funzioni e Operatori. Un esempio è la clausola IS NULL.

Le costanti sono già state discusse in Sezione 4.1.2, «Costanti». Nelle sezioni seguenti vengono discusse le opzioni rimanenti.

4.2.1. Riferimenti di colonna

Ci si può riferire a una colonna nella forma:

correlation.columnname

correlation è il nome di una tabella (possibilimente qualificata con il nome di uno schema), o un alias per una tabella definita dai significati di una clausola FROM. Il nome della correlazione e il punto di separazione possono essere omessi se il nome della colonna è unico fra tutte le tabelle usate nella query corrente. (Si veda anche Capitolo 7, Query).

4.2.2. Parametri posizionali

Un riferimento a parametro posizionale viene usato per indicare un valore che è fornito esternamente a un'istruzione SQL. I parametri sono usati in definizioni di funzioni SQL e in query preparate. Alcune librerie client supportano anche la specificazione di valori separatamente dalla stringa di comando SQL, nel qual caso i parametri sono usati per riferirsi a valori di dati fuori-della-linea. La forma di un riferimento a parametro è:

$number

Per esempio, considerare la definizione di una funzione, dept, come:

CREATE FUNCTION dept(text) RETURNS dept
    AS $$ SELECT * FROM dept WHERE name = $1 $$
    LANGUAGE SQL;

Qui, $1 si riferisce al valore del primo argomento di funzione nel momento che la funzione viene invocata.

4.2.3. Sottoscript

Se un'espressione restituisce un valore di tipo array, allora è possibile estrarre un elemento specifico dell'array scrivendo

expression[subscript]

o possono essere estratti molteplici elementi adiacenti (una «fetta di array») scrivendo

expression[lower_subscript:upper_subscript]

(Qui, le parentesi quadre [ ] sono intese per apparire letteralmente). Ogni subscript è di per sè un'espressione, che deve restituire un valore intero.

[Nota]

Nota

Nota per il revisore: TODO

In general the array expression must be parenthesized, but the parentheses can be omitted when the expression to be subscripted is just a column reference or positional parameter. Also, multiple subscripts can be concatenated when the original array is multidimensional. For example:

mytable.arraycolumn[4]
mytable.two_d_column[17][34]
$1[10:42]
(arrayfunction(a,b))[42]

Le parentesi nell'ultimo esempio sono richieste. Si veda Sezione 8.14, «Array» per maggiori informazioni sugli array.

4.2.4. Selezione di campi

Se un'espressione restituisce un valore di un tipo composto (tipo riga), allora un campo specifico della riga può essere estratto scrivendo

expression.fieldname

In generale la riga expression deve essere messa tra parentesi, ma le parentesi possono essere omesse quando l'espressione da essere selezionata è semplicemente un riferimento a una tabella o un parametro posizionale. Per esempio:

mytable.mycolumn
$1.somecolumn
(rowfunction(a,b)).col3

(Per questo, un riferimento qualificato a una colonna attualmente è solo un caso speciale della sintassi di selezione campo). Un caso speciale importante è l'estrazione di un campo da una colonna di tabella che è di tipo composto:

(compositecol).somefield
(mytable.compositecol).somefield

Qui le parentesi sono necessarie per mostrare che compositecol è un nome di colonna è non il nome di una tabella, o che mytable è il nome di una tabella e non il nome di uno schema nel secondo caso.

4.2.5. Invocazioni di operatore

Ci sono tre possibili sintassi per l'invocazione di un operatore:

expression operator expression (binary infix operator)
operator expression (unary prefix operator)
expression operator (unary postfix operator)

dove il token operator segue le regole sintattiche di Sezione 4.1.3, «Operatori», o è una delle parole chiave AND, OR o NOT, o è il nome di un operatore qualificato nella forma:

OPERATOR(schema.operatorname)

Quali particolari operatori esistono e se sono unari o binari dipernde da quali operatori sono stati definiti dal sistema o dall'utente. Capitolo 9, Funzioni e Operatori descrive gli operatori inclusi.

4.2.6. Chiamate di funzione

La sintassi per una chiamata di funzione è il nome di una funzione (possibilmente qualificato con il nome di uno schema) seguito dal suo elenco di argomenti racchiuso tra parentesi:

function_name ([expression [, expression ... ]] )

Per esempio, la seguenta calcola la radice quadrata di 2:

sqrt(2)

L'elenco delle funzioni incluse si trova in Capitolo 9, Funzioni e Operatori. Altre funzioni possono essere aggiunte dall'utente.

Gli argomenti possono opzionalmente avere nomi attaccati. Si veda Sezione 4.3, «Chiamare funzioni» per dettagli.

4.2.7. Espressioni aggregate

Una espressione aggregata rappresenta l'applicazione di una funzione aggregata attraverso le righe selezionate da una query. Una funzione aggregata riduce input multipli a un singolo valore di output, come la somma o la media degli input. La sintassi di un'espressione aggregata è una delle seguenti:

aggregate_name (expression [ , ... ] [ order_by_clause ] )
aggregate_name (ALL expression [ , ... ] [ order_by_clause ] )
aggregate_name (DISTINCT expression [ , ... ] [ order_by_clause ] )
aggregate_name ( * )

dove aggregate_name è un'aggregata definita precedentemente (possibilmente qualificata con il nome di uno schema), expression è qualsiasi espressione di valore che di per sè non contiene un'espressione aggregata o una chiamata a funzione finestra, e order_by_clause è una clausola ORDER BY come descritto sotto.

La prima forma di espressione aggregata invoca l'aggregata una volta per ogni riga di input. La seconda forma è uguale alla prima, dato che ALL è il predefinito. La terza forma invoca l'aggregata una volta per ogni valore distinto dell'espressione (o insieme distinto di valori, per molteplici espressioni) trovato nelle righe di input. L'ultima forma invoca l'aggregata una volta per ogni riga di input; dato che non è specificato nessun particolare valore di input, generalmente è utile solo per la funzione aggregata count(*).

La maggior parte delle funzioni aggregate ignorano input null, così quelle righe nelle quali una o più espressione/i restituisce null sono scartate. Possiamo assumere questo come vero, a meno che non sia diversamente specificato, per tutte le aggregate incluse.

Per esempio, count(*) restituisce il numero totale di righe di input; count(f1) restituisce il numero di righe di input nelle quali f1 non è null, dato che count ignora i valori null; e count(distinct f1) restituisce il numero di valori non null distinti di f1.

Di solito, le righe di input sono date in pasto alla funzione aggregata in ordine sparso. In molti casi questo non ha importanza; per esempio, min produce lo stesso risultato a prescindere dall'ordine in cui riceve gli input. Comunque, alcune funzioni aggregate (tipo array_agg e string_agg) producono risultati che dipendono dall'ordinamento delle righe di input. Quando si usa un'aggregata del genere, è possibile usare order_by_clause per specificare l'ordinamento desiderato. order_by_clause ha la stessa sintassi di una clausola ORDER BY a livello di query, come descritto in Sezione 7.5, «Classificazione di righe», ad eccezione che le sue espressioni sono sempre soltanto espressioni e non possono essere nomi di colonne di output o numeri. Per esempio:

SELECT array_agg(a ORDER BY b DESC) FROM table;

Quando si ha a che fare con funzioni aggregate che hanno molteplici argomenti, notare che la clausola ORDER BY va dopo tutti gli argomenti dell'aggregata. Per esempio, scrivere:

SELECT string_agg(a, ',' ORDER BY a) FROM table;

non:

SELECT string_agg(a ORDER BY a, ',') FROM table;  -- non corretto

L'ultimo è sintatticamente valido, ma rappresenta una chiamata di una funzione aggregata con singolo argomento con due chiavi ORDER BY (la seconda è abbastanza inutile dato che è una costante).

Se viene specificato DISTINCT in aggiunta a una order_by_clause, allora tutte le espressioni ORDER BY devono corrispondere a argomenti dell'aggregata; cioè, non è possibile ordinare in base a un'espressione che non è inclusa nell'elenco DISTINCT.

[Nota]

Nota

L'abilità di specificare sia DISTINCT che ORDER BY in una funzione aggregata è un'estensione di PostgreSQL

Le funzioni aggregate predefinite sono descritte in Sezione 9.18, «Funzioni aggregate». Altre funzioni aggregate possono essere aggiunte dall'utente.

Un'espressione aggregata può apparire solo nell'elenco risultatante o nella clausola HAVING di un comando SELECT. È proibito in altre clausole, tipo la WHERE, dato che queste clausole sono valutate logicamente prima che siano formati i risultati delle aggregate.

Quando un'espressione aggregata appare in una sottoquery (si veda Sezione 4.2.10, «Sottoquery scalari» e Sezione 9.20, «Espressioni sottoquery»), l'aggregata è valutata normalmente sulle righe della sottoquery. Viene generata un'eccezione se gli argomenti dell'aggregata contengono solo variabili di livello esterno: l'aggregata quindi appartiene al livello esterno più vicino, ed è valutata sulle righe della query. L'espressione aggregata in totale è quindi un riferimento esterno per la sottoquery nella quale appare, e agisce come una costante su ogni valutazione di quella sottoquery. La restrizione di apparire solo nell'elenco risultante o nella clausola HAVING viene applicata a livello della query alla aquale l'aggregata appartiene.

4.2.8. Chiamate a funzioni finestra

Una chiamata di funzione finestra rappresenta l'applicazione di una funzione simil-aggregata su qualche porzione delle righe selezionate dalla query. A differenza delle chiamate alle normali funzioni aggregate, questo non è legato al raggruppamento delle righe selezionate in una singola riga di output - ogni riga rimane separata nell'output della query. Comunque la funzione finestra è capace di eseguire lo scan di tutte le righe che sarebbero parte del gruppo della riga corrente in accordo con la specifica di raggrupamento (elenco PARTITION BY) della chiamata a funzione finestra. La sintassi di una chiamata a funzione finestra è una delle seguenti:

function_name ([expression [, expression ... ]]) OVER ( window_definition )
function_name ([expression [, expression ... ]]) OVER window_name
function_name ( * ) OVER ( window_definition )
function_name ( * ) OVER window_name

dove window_definition ha la sintassi

[ existing_window_name ]
[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ frame_clause ]

e l'opzionale frame_clause può essere una tra

[ RANGE | ROWS ] frame_start
[ RANGE | ROWS ] BETWEEN frame_start AND frame_end

dove frame_start e frame_end possono essere una tra

UNBOUNDED PRECEDING
value PRECEDING
CURRENT ROW
value FOLLOWING
UNBOUNDED FOLLOWING

Qui, expression rappresenta qualsiasi espressione di valore che di per sè non contiene chiamate a funzioni finestra. Gli elenchi PARTITION BY e ORDER BY hanno essenzialmente la stessa sintassi e semantica delle clausole GROUP BY e ORDER BY dell'intera query, ad eccezione che le loro espressioni sono sempre soltanto espressioni e non possono essere nomi di colonne di output o numeri. window_name è un riferimento a una specificazione di finestra definita nella clausola WINDOW della query. Specificazioni di finestra nominate sono di solito riferite con OVER window_name, ma è possibile anche scrivere il nome di una finestra tra parentesi e quindi opzionalmente fornire una clausola di ordinamento e/o clausa di cornice (la finestra referenziata non deve avere queste clausole, se esse sono fornite qui). Quest'ultima sintassi segue le stesse regole per la modifica di un nome di finestra esistente all'interno della clausola WINDOW; si veda la pagina di riferimento SELECT(7) per dettagli.

La frame_clause specifica l'insieme di righe che costituiscono la cornice di finestra, per quelle funzioni finestra che agiscono sulla cornice invece che sull'intera finestra. Se frame_end viene omesso viene preso come predefinito CURRENT ROW. Restrizioni sono che frame_start non può essere UNBOUNDED FOLLOWING, frame_end non può essere UNBOUNDED PRECEDING, e la scelta frame_end non può apparire prima della scelta frame_start nell'elenco sopra - per esempio RANGE BETWEEN CURRENT ROW AND value PRECEDING non è consentito. L'opzione predefinita per la definizione della cornice è RANGE UNBOUNDED PRECEDING, che è lo stesso di RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW; essa imposta la cornice per essere composta da tutte le righe dall'inizio della partizione in su fino alla riga corrente nell'ordinamento ORDER BY (che significa tutte le righe se non c'è ORDER BY). In generale, UNBOUNDED PRECEDING significa che la cornice comincia con la prima riga della partizione, e similmente UNBOUNDED FOLLOWING significa che la cornice termina con l'ultima riga della partizione (a prescindere dalla modalità RANGE o ROWS). In modalità ROWS, CURRENT ROW significa che la cornice comincia o finisce con la riga corrente; ma in modalità RANGE significa che la cornice somincia o finisce con il primo o ultimo pari della riga corrente nell'ordinamento ORDER BY. I casi value PRECEDING e value FOLLOWING sono attualmente permessi solo in modalità ROWS. Essi indicano che la cornice comincia o finisce con la riga quelle tante righe prima o dopo la corrente. value dev'essere un'espressione intera non contenente variabili, funzioni aggregate, o funzioni finestra. Il valore non deve essere null o negativo; ma può essere zero, che seleziona la riga corrente.

Le funzioni finestra incluse sono descritte nella Tabella 9.44, «Funzioni window di utilizzo generale». Altre funzioni finestra possono essere aggiunte dall'utente. In più, qualsiasi funzione aggregata inclusa o definita dall'utente può essere usata come funzione finestra.

Le sintassi che usano * sono usate per chiamare funzioni aggregate senza parametri tipo funzioni finestra, per esempio count(*) OVER (PARTITION BY x ORDER BY y). Di norma * non è usato per funzioni finestra non aggregate. Funzioni fiestra aggregate, a differenza di funzioni aggregate normali, non permettono l'utilizzo di DISTINCT o ORDER BY all'interno dell'elenco degli argomenti di funzione.

Chiamate a funzioni finestra sono permesse sono nell'elenco SELECT e nella clausola ORDER BY della query.

Maggiori informazioni sulle funzioni finestra possono essere trovate in Sezione 3.5, «Funzioni di Finestra», Sezione 9.19, «Funzioni window», Sezione 7.2.4, «Elaborazione di funzioni window».

4.2.9. Conversioni di tipo

Una conversione di tipo specifica una conversione da un tipo di dato ad un altro. PostgreSQL™ accetta due sintassi equivalenti per conversioni di tipo:

CAST ( expression AS type )
expression::type

La sintassi CAST è conforma a SQL; la sintassi con :: è storica di PostgreSQL™.

Quando viene applicata una conversione a una espressione di valore di un tipo conosciuto, essa rappresenta una conversione di tipo dirante l'esecuzione. La conversione avrà successo solo se è stata definita un'operazione di conversione di tipo adatta. Considerare che questo è leggermente diverso dall'uso di conversioni con costanti, come visto in Sezione 4.1.2.7, «Costanti di altri tipi». Una conversione applicata a stringhe letterali spoglie rappresenta l'assegnamento iniziale di un tipo a un valore costante letterale, e così succederà per ogni tipo (se il contenuto della stringa letterale è sintassi di input accettabile per il tipo di dato).

Un'esplicita conversione di tipo può, di solito, essere omessa se non c'è ambiguità sul tipo che un'espressione di valore deve produrre (per esempio, quando è assegnata a una colonna di tabella); il sistema applicherà automaticamente una conversione di tipo in questi casi. Comunque, una conversione automatica viene fatta solo per conversioni che sono indicate come «OK to apply implicitly» nei cataloghi di sistema. Altre conversioni devono essere invocate con sintassi di conversione esplicita. Questa restrizione è intesa per prevenire conversioni sorprendenti dall'essere applicate silenziosamente.

È anche possibile specificare una conversione di tipo usando una sintassi simile a una funzione:

typename ( expression )

In ogni caso, questo funziona solo per tipi i chui nomi sono validi anche come nomi di funzione. Per esempio, double precision non può essere usato in questo modo, ma l'equivalente float8 può. Inoltre, i nomi interval, time, e timestamp possono essere usati solo in questo modo se sono espresse tra doppi apici, causa conflitti sintattici. Inoltre, l'uso di sintassi di conversione stile-funzione porta inconsistenza e dovrebbe essere evitato.

[Nota]

Nota

La sintassi stile-funzione è di fatto semplicemente una chiamata di funzione. Quando una delle due sintassi di conversione standard viene usata per compiere una conversione durante l'esecuzione, sarà internamente invocata una funzione registrata per eseguire la conversione. Per convenzione, queste funzioni di conversione hanno lo stesso nome del loro tipo di output, e così la «sintassi stile-funzione» non è altro che un'invocazione diretta della funzione di conversione sottostante. Ovviamente, un'applicazione portabile non dovrebbe usare questo comportamento. Per ulteriori dettagli si veda CREATE CAST(7).

4.2.10. Sottoquery scalari

Una sottoquery scalare è una normale query SELECT tra parentesi che restituisce esattamente una riga con una colonna. (Si veda Capitolo 7, Query per informazioni sulla scrittura di query). La query SELECT viene eseguita e il singolo valore restituito viene usato nell'espressione di valore circostante. Usare una query che restituisce più di una riga o più di una colonna come query scalare è un errore. (Se, durante un'esecuzione particolare, la sottoquery non restituisce righe, non c'è errore; il risultato scalare viene considerato essere null). La sottoquery può riferirsi a variabili dalla query circostante, che agiranno come costanti durante la valutazione della sottoquery. Si veda anche Sezione 9.20, «Espressioni sottoquery» per altre espressioni riguardanti le sottoquery.

L'esempio seguente trova la popolazione cittadina maggiore in ogni stato:

SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name)
    FROM states;

4.2.11. Costruttori di array

Un costruttore di array è un'espressione che costruisce un valore array usando valori per i suoi elementi membri. Un costruttore di array semplice consiste della parola chiave ARRAY, una parentesi quadra sinistra [, un elenco di espressioni (separate da virgole) per i valori degli elementi dell'array, ed infine una parentesi quadra destra ]. Per esempio:

SELECT ARRAY[1,2,3+4];
  array
---------
 {1,2,7}
(1 row)

In maniera predefinita, il tipo degli elementi dell'array è il tipo delle espressioni membro, determinato usando le stesse regole dei costruttori UNION o CASE (si veda Sezione 10.5, «UNION, CASE, and Related Constructs»). Si può sovrascrivere questo convertendo esplicitamente il costruttore dell'array al tipo desiderato, per esempio:

SELECT ARRAY[1,2,22.7]::integer[];
  array
----------
 {1,2,23}
(1 row)

Questo ha lo stesso effetto di convertire ogni espressione al tipo dell'elemento dell'array individualmente. Per maggiori informazioni sulla conversione, si veda Sezione 4.2.9, «Conversioni di tipo».

Valori di array multidimensionali possono essere costruiti annidando costruttori di array. Nei costruttori interni, la parola chiave ARRAY può essere omessa. Questi esempi producono lo stesso risultato:

SELECT ARRAY[ARRAY[1,2], ARRAY[3,4]];
     array
---------------
 {{1,2},{3,4}}
(1 row)

SELECT ARRAY[[1,2],[3,4]];
     array
---------------
 {{1,2},{3,4}}
(1 row)

Dato che array multidimensionali devono essere rettangolari, i costruttori interni allo stesso livello devono produrre sotto-array di dimensioni identiche. Qualsiasi conversione applicata al costruttore ARRAY esterno si propaga automaticamente a tutti i costruttori interni.

Elementi costruttore di array multidimansionali possono essere qualsiasi cosa che restituisce un array di tipo corretto, non solo un costruttore di sotto-ARRAY. Per esempio:

CREATE TABLE arr(f1 int[], f2 int[]);

INSERT INTO arr VALUES (ARRAY[[1,2],[3,4]], ARRAY[[5,6],[7,8]]);

SELECT ARRAY[f1, f2, '{{9,10},{11,12}}'::int[]] FROM arr;
                     array
------------------------------------------------
 {{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}
(1 row)

È possibile costruire un array vuoto, ma dato che è impossibile avere un array senza tipo, si deve convertire esplicitamente l'array vuoto al tipo desiderato. Per esempio:

SELECT ARRAY[]::integer[];
 array
-------
 {}
(1 row)

È anche possibile costruire un array dai risultati di una sottoquery. In questa forma, il costruttore di array viene scritto con la parola chiave ARRAY seguita da una sottoquery (non tra parentesi). Per esempio:

SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
                          ?column?
-------------------------------------------------------------
 {2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31}
(1 row)

La sottoquery deve restituire una singola colonna. L'array monodimensionale risultante avrà un elemento per ogni riga nel risultato della sottoquery, con un tipo di elemento corrispondente a quello della colonna di output della sottoquery.

I sottoscript di un valore array costruiti con ARRAY cominciano sempre da uno. Per maggiori informationi sugli array, si veda Sezione 8.14, «Array».

4.2.12. Costruttori di riga

Un costruttore di riga è un'espressione che costruisce un valore di riga (chiamato anche valore composto) usando valori per i suoi campi membro. Un costruttore di riga consiste della parola chiave ROW, una parentesi sinistra, zero o più espressioni (separate da virgole) per i valori dei campi della riga, e infine una parentesi destra. Per esempio:

SELECT ROW(1,2.5,'this is a test');

La parola chiave ROW è opzionale quando c'è più di una espressione nell'elenco.

Un costruttore di riga può includere la sintassi rowvalue.*, che sarà espansa ad un elenco di elementi del tipo della riga, esattamente come occorre quando la sintassi .* viene usata al livello superiore di un elenco SELECT. Per esempio, se la tabella t ha le colonne f1 e f2, questi esempi sono gli stessi:

SELECT ROW(t.*, 42) FROM t;
SELECT ROW(t.f1, t.f2, 42) FROM t;

[Nota]

Nota

Prima di PostgreSQL™ 8.2, la sintassi .* non fu espansa, così scrivere ROW(t.*, 42) crea una riga con due campi di cui il primo campo era un altro valore di riga. Il nuovo comportamento di solito è più utile. Se si ha bisogno del vecchio comportamento di valori di riga annidati, scrivere il valore di riga interno senza .*, per esempio ROW(t, 42).

In maniera predefinita, il valore creato da un'espressione ROW è di tipo record anonimo. Se necessario, può essere convertito a un tipo composto - sia il tipo di riga di una tabella, che un tipo composto creato con CREATE TYPE AS. Una conversione esplicita potrebbe essere necessaria per evitare ambiguità. Per esempio:

CREATE TABLE mytable(f1 int, f2 float, f3 text);

CREATE FUNCTION getf1(mytable) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;

-- No cast needed since only one getf1() exists
SELECT getf1(ROW(1,2.5,'this is a test'));
 getf1
-------
     1
(1 row)

CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);

CREATE FUNCTION getf1(myrowtype) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;

-- Now we need a cast to indicate which function to call:
SELECT getf1(ROW(1,2.5,'this is a test'));
ERROR:  function getf1(record) is not unique

SELECT getf1(ROW(1,2.5,'this is a test')::mytable);
 getf1
-------
     1
(1 row)

SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));
 getf1
-------
    11
(1 row)

Costruttori di riga possono essere usati per creare valori composti da essere immagazzinati in colonne di tabella con tipi composti, o per essere passati a funzioni che accettano in parametro composto. Inoltre, è possibile confrontare due valori di riga o testare una riga con IS NULL o IS NOT NULL, per esempio:

SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');

SELECT ROW(table.*) IS NULL FROM table;  -- trova tutte le righe null

Per maggiori dettagli si veda Sezione 9.21, «Confronti di array e righe». Costruttori di riga possono essere usati anche in connessione con sottoquery, come discusso in Sezione 9.20, «Espressioni sottoquery».

4.2.13. Regole di valutazione di espressione

L'ordine per la valutazione di sottoespressioni non è definito. In particolare, gli input di un operatore o funzione non sono necessariamente valutati da sinistra a destra o in qualsiasi altro ordine prefissato.

Inoltre, se il risultato di un'espressione può essere determinato valutandone solo alcune parti, allora altre sottoespressioni potrebbero non essere valutate per niente. Per esempio, se si scrive:

SELECT true OR somefunc();

allora somefunc() (probabilmente) non sarebbe chiamata per niente. Allo stesso modo se si scrive:

SELECT somefunc() OR true;

Notare che questo non è lo stesso dello «short-circuiting» da sinistra a destra di operatori booleani che sono presenti in alcuni linguaggi di programmazione.

Di conseguenza, non è saggio usare funzioni con effetti collaterali come parte di espressioni complesse. È particolarmente pericoloso fare conto sugli effetti collaterlai o sull'ordine di valutazione nelle clausole WHERE e HAVING, dato che queste clausole vengono ri-processate estensivamente come parte dello sviluppo di un query plan. Espressioni booleane (combinazioni di AND/OR/NOT) in quelle clausole possono essere riorganizzate in qualsiasi modo permesso dalle leggi dell'algebra booleana.

When it is essential to force evaluation order, a CASE Quando è essenziale forzare l'ordine di valutazione, può essere usato un costrutto CASE construct (see Sezione 9.16, «Espressioni condizionali») can be (si veda Sezione 9.16, «Espressioni condizionali»). used. For example, this is an untrustworthy way of trying to Per esempio, questo è un modo inaffidabile di provare ad evittare avoid division by zero in a WHERE clause: divisioni per zero in una clausola WHERE:

SELECT ... WHERE x > 0 AND y/x > 1.5;

Ma questo è sicuro:

SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;

Un costrutto CASE usado in questo modo rifiuterà tentativi di ottimizzazione, così dovrebbe essere usato solo se necessario. (In questo particolare esempio, sarebbe meglio evitare il problema scrivendo y > 1.5*x).

Documentazione di PostgreSQL 9.0 > Il linguaggio SQL > Sintassi SQL > Espressioni di valore
PrecedenteSintassi SQLChiamare funzioniSuccessivo