2013-08-01 13 views
7

Ho bisogno di aggiornare una tabella utilizzando un valore cancellato da un'altra tabella. La situazione è un segnapunti di voto di commento simile a quello su SO. Sto usando python per far funzionare i postgres, ma questo non dovrebbe fare la differenza.Utilizzo del valore di ritorno da DELETE per UPDATE in Postgres

query=""" 
UPDATE comment SET score=score-(DELETE FROM history 
           WHERE commentId=%(commentId)s AND 
             userIdentity=%(userIdentity)s RETURNING vote) 
WHERE commentId=%(commentId)s; 
""" 
cursor.execute(query, data) 

L'errore si pone a (DELETE FROM; si verifica un errore di sintassi. Posso sostituire l'istruzione DELETE con una dichiarazione SELECT e funzionerà, c'è qualcosa che mi manca qui? Voglio usare il valore restituito in un aggiornamento. È possibile? Tutto aiuta.

schema Relevant:

CREATE TABLE history (
    commentId bigint, 
    vote int, 
    userIdentity varchar(256), 
); 
CREATE TABLE comment (
    id bigint, 
    score bigint, 
); 

history.vote è normalmente 1 o -1.

risposta

16

PostgreSQL non consente il mix delle istruzioni UPDATE e DELETE come sottoquery.

È possibile utilizzare una diversa strategia po '- aggiornabile CTE

 
postgres=# WITH t1 AS (DELETE FROM foo RETURNING *), 
       t2 AS (INSERT INTO deleted 
          SELECT * FROM t1 RETURNING *) 
      SELECT max(a) FROM t2; 

così

 
postgres=# CREATE TABLE comment(id int, score int); 
CREATE TABLE 
postgres=# CREATE TABLE history(id int, comment_id int, vote int); 
CREATE TABLE 
postgres=# INSERT INTO comment values(1,10); 
INSERT 0 1 
postgres=# INSERT INTO comment values(2,20); 
INSERT 0 1 
postgres=# INSERT INTO history values(1,1,5); 
INSERT 0 1 
postgres=# WITH t1 AS (DELETE FROM history 
         WHERE id=1 
         RETURNING comment_id, vote) 
      UPDATE comment SET score=score-t1.vote 
      FROM t1 
      WHERE t1.comment_id=comment.id; 
UPDATE 1 
postgres=# select * from comment; 
id | score 
----+------- 
    2 | 20 
    1 |  5 
(2 rows) 

Attenzione: richiede 9.1 o più recente

+0

Questo funziona come previsto, la rimozione del voto nella storia e aggiornare il punteggio di voto atomicamente. Grazie! – JDong

+0

Wow, è incredibile quanto puoi fare in una dichiarazione con 'WITH'. – danneu

Problemi correlati