2013-08-01 40 views
7

Tôi cần cập nhật bảng bằng giá trị đã xóa từ một bảng khác. Tình huống là một người ghi phiếu bầu bình chọn tương tự như người ghi trên SO. Tôi đang sử dụng python để làm việc postgres, nhưng điều đó không nên tạo sự khác biệt.Sử dụng giá trị trả về từ DELETE cho CẬP NHẬT trong 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ỗi phát sinh tại (DELETE FROM; một lỗi cú pháp phát sinh. Tôi có thể thay thế câu lệnh DELETE bằng tuyên bố SELECT và nó sẽ hoạt động, có điều gì tôi thiếu ở đây không? Tôi muốn sử dụng giá trị trả về trong bản cập nhật. Điều này có thể không? Bất cứ điều gì giúp.

schema có liên quan:

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

history.vote thường 1 hoặc -1.

Trả lời

16

PostgreSQL không cho phép kết hợp câu lệnh UPDATE và DELETE làm truy vấn phụ.

Bạn có thể sử dụng một chút chiến lược khác nhau - updateable CTE

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

nên

 
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) 

Chú ý: Nó đòi hỏi 9.1 hoặc mới hơn

+0

này hoạt động như mong muốn, loại bỏ các lá phiếu trong lịch sử và cập nhật điểm số phiếu bầu một cách nguyên tử. Cảm ơn! – JDong

+0

Chà, thật ngạc nhiên là bạn có thể làm được bao nhiêu trong một câu lệnh với 'WITH'. – danneu

Các vấn đề liên quan