2013-08-01 13 views
7

Potrzebuję zaktualizować tabelę przy użyciu wartości usuniętej z innej tabeli. Sytuacja jest podobna do tej, która dotyczy SO. Używam Pythona do pracy PostgreSQL, ale to nie powinno mieć znaczenia.Używanie wartości zwracanej z polecenia DELETE dla aktualizacji w Postgresie

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) 

Błąd pojawia się na (DELETE FROM; powstaje błąd składni. Mogę zastąpić oświadczenie DELETE oświadczeniem SELECT i będzie działać, czy jest coś, czego tu brakuje? Chcę użyć zwracanej wartości w aktualizacji. czy to możliwe? Wszystko pomaga.

dowiemy się z schematu:

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

history.vote normalnie 1 lub -1.

Odpowiedz

16

PostgreSQL nie zezwala na mieszanie instrukcji UPDATE i DELETE jako podzapytanie.

Można użyć trochę inną strategię - updateable CTE

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

tak

 
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) 

Uwaga: To wymaga 9.1 lub nowsza

+0

ten działa zgodnie z przeznaczeniem, usuwając głosowanie w historii i aktualizowanie wyniku głosowania atomicznie. Dzięki! – JDong

+0

Wow, to niesamowite, ile możesz zrobić w jednym komunikacie z 'WITH'. – danneu

Powiązane problemy