2011-08-25 13 views
9

I isolatet il problema da una query molto più complessa. Qui lo scenario di provaImpossibile selezionare dalla clausola UPDATE RETURNING in postgres

DROP TABLE test; 
CREATE TABLE test (
    id integer, 
    description varchar(100) 
); 

INSERT INTO test(id, description) VALUES (1,'new'); 
INSERT INTO test(id, description) VALUES (2,'new'); 

Se eseguo la query:

SELECT * FROM test WHERE id IN (UPDATE test set description='test' RETURNING id) 

sto ottenendo il seguente errore:

errore: Errore di sintassi al o "test" nei pressi di LINEA 1: SELECT * FROM test WHERE id (UPDATE test set description = 'test' RE ... ^

*** Fehler ** *

ERRORE: errore di sintassi in prossimità o "test" Stato SQL: 42601 Zeichen: 37

Tuttavia, se si esegue solo lo statemennt

UPDATE test set value='test' RETURNING id 

ottengo un risultato con 2 file:

Se substitude quel risultato avrei una query come:

SELECT * FROM test WHERE id IN (1,2); 

con il risultato:

1; "test" 2; "test"

Perché non ottengo lo stesso risultato con la mia affermazione iniziale?

+1

Devono essere prospetti separati. È probabile che il fatto che due righe vengano aggiornate causerà problemi, mai provato a RESTITARE quando più di una riga/valore sta tornando. –

risposta

23

Prima di PostgreSQL 9.1 INSERT/UPDATE/DELETE poteva essere utilizzato solo come istruzioni di primo livello. Questo è il motivo per cui ricevi un errore di sintassi.

A partire da 9.1 è possibile utilizzare istruzioni di modifica dei dati con espressioni di tabella comuni.La query di esempio sarà simile a questa:

WITH updated AS (UPDATE test SET description = 'test' RETURNING id) 
SELECT * FROM test WHERE id IN (SELECT id FROM updated); 

Fare attenzione con la selezione dalla tabella appena modificata. Puoi ottenere risultati confusi in questo modo. Poiché le query vengono eseguite nella stessa istantanea, SELECT non vedrà gli effetti dell'istruzione UPDATE.

+2

FYI, l'approccio CTE non funziona con INSERT –

+0

Quindi questo 'SELECT' restituirebbe l'id e il vecchio valore di descrizione' 'new'' invece il valore aggiornato '' test''? – Davos

6

Si aggiornano due righe nella query UPDATE, si aggiunge una clausola WHERE per limitare le righe interessate.

UPDATE test SET description = 'test' WHERE id = 1 RETURNING id 

per restituire una singola riga .

+0

SELEZIONA * FROM test WHERE id IN (UPDATE test SET value = 'test' WHERE id = 1 ID ROTAZIONE) mostra lo stesso errore – markus

+0

aggiornato "valore" a "descrizione", stesso numero – markus

3

Ti manca uno IN: ... WHERE id IN (UPDATE ...?

However if I only run the statemennt "UPDATE test set value='test' RETURNING id", I get a result with 2 rows. Why is that?

tuo UPDATE non ha WHERE clausola e quindi aggiorna ogni riga, di cui ci sono due.

+0

sì, appena aggiornato – markus

+0

Il problema è non l'aggiornamento RESTITUZIONE, che funziona con e senza clausola where. Il problema è con la selezione intorno ad esso. – markus

1

Non si limita la clausola where. È necessario avere id = (blahblah) o id IN (blahblah)

1
UPDATE test set description='test' RETURNING * 

fornirebbe il set di risultati che ci si aspetta dalla query iniziale.

Ma sospetto che stavate provando qualcosa di più complesso?

0
DROP TABLE IF EXISTS test_tab; 

CREATE TABLE test_tab (
    id integer, 
    description varchar(100) 
); 

INSERT INTO test_tab(id, description) VALUES (1,'new'); 
INSERT INTO test_tab(id, description) VALUES (2,'new'); 

SELECT * from test_tab; 

DO $$ 
DECLARE 
    myID test_tab.id%TYPE; 
    testID test_tab.id%TYPE; 
    cur_IDs CURSOR for select id from test_tab; 
BEGIN 
    OPEN cur_IDs; 
    LOOP 
     FETCH cur_IDs into testID; 
     EXIT WHEN testID is NULL; 

     UPDATE test_tab SET description='test' WHERE id = testID RETURNING id into myID; 
     raise notice 'myID %', myID; 
    END LOOP; 
    CLOSE cur_IDs; 
END$$; 


DROP TABLE IF EXISTS test_tab; 
-1

Sono inoltre da formiche Aasma, se selezionate sullo stesso tavolo, utilizzando:

WITH updated AS (UPDATE test SET description = 'test' RETURNING id, description) 
SELECT * FROM updated; 
Problemi correlati