2011-07-05 31 views
13

Tôi đang cố gắng xóa một hàng khỏi một bảng và chèn nó với một số dữ liệu bổ sung vào một bảng khác. Tôi biết điều này có thể được thực hiện trong hai lệnh riêng biệt, một để xóa và một lệnh khác để chèn vào bảng mới. Tuy nhiên tôi đang cố gắng để kết hợp chúng và nó không được làm việc, đây là câu hỏi của tôi cho đến nay:Làm thế nào tôi có thể chèn trả về DELETE vào INSERT trong postgresql?

insert into b (one,two,num) values delete from a where id = 1 returning one, two, 5;

Khi chạy mà tôi nhận được lỗi sau:

ERROR: syntax error at or near "delete"

bất cứ ai có thể chỉ ra như thế nào để thực hiện điều này, hoặc là có một cách tốt hơn? Hay là điều này không thể thực hiện được?

Trả lời

4

Trước PostgreSQL 9.1 bạn có thể tạo một hàm dễ bay hơi như (chưa được kiểm tra) này:

create function move_from_a_to_b(_id integer, _num integer) 
returns void language plpgsql volatile as 
$$ 
    declare 
    _one integer; 
    _two integer; 
    begin 
    delete from a where id = _id returning one, two into strict _one, _two; 
    insert into b (one,two,num) values (_one, _two, _num); 
    end; 
$$ 

và sau đó chỉ cần sử dụng select move_from_a_to_b(1, 5). Một hàm có lợi thế hơn hai câu lệnh rằng nó sẽ luôn luôn chạy trong một giao dịch duy nhất - không cần phải bắt đầu và cam kết giao dịch một cách rõ ràng trong mã máy khách.

+0

Làm việc cho tôi, cảm ơn bạn! – NoToBagels

0

Cú pháp bạn có ở đó không hợp lệ. 2 câu là cách tốt nhất để làm điều này. Cách trực quan nhất để làm điều đó là thực hiện việc chèn đầu tiên và xóa lần thứ hai.

-1

Là "AI W", hai câu lệnh chắc chắn là lựa chọn tốt nhất cho bạn, nhưng bạn cũng có thể xem xét viết trình kích hoạt cho điều đó. Mỗi khi một cái gì đó bị xóa trong bảng đầu tiên của bạn, một cái khác sẽ được lấp đầy.

32

Bạn không thể thực hiện việc này trước khi PostgreSQL 9.1 chưa được phát hành. Và sau đó là cú pháp sẽ là

WITH foo AS (DELETE FROM a WHERE id = 1 RETURNING one, two, 5) 
    INSERT INTO b (one, two, num) SELECT * FROM foo; 
+0

Cảm ơn bạn rất nhiều vì câu trả lời này, khi tôi chuyển sang 9.1 Tôi sẽ sử dụng điều này, bây giờ phương pháp của Tometzky sẽ phải làm. – lanrat

1

Đối với tất cả phiên bản của PostgreSQL, bạn có thể tạo hàm kích hoạt để xóa các hàng khỏi bảng và chèn chúng vào bảng khác. Nhưng nó có vẻ chậm hơn chèn số lượng lớn được phát hành trong PostgreSQL 9.1. Bạn chỉ cần di chuyển dữ liệu cũ vào bảng khác trước khi nó bị xóa. Này được thực hiện với kiểu dữ liệu OLD:

CREATE FUNCTION moveDeleted() RETURNS trigger AS $$ 
    BEGIN 
     INSERT INTO another_table VALUES(OLD.column1, OLD.column2,...); 
     RETURN OLD; 
    END; 
$$ LANGUAGE plpgsql; 

CREATE TRIGGER moveDeleted 
BEFORE DELETE ON table 
    FOR EACH ROW 
     EXECUTE PROCEDURE moveDeleted(); 

Như trên câu trả lời, sau khi PostgreSQL 9.1 bạn có thể làm điều này:

WITH tmp AS (DELETE FROM table RETURNING column1, column2, ...) 
    INSERT INTO another_table (column1, column2, ...) SELECT * FROM tmp; 
Các vấn đề liên quan