2011-07-05 9 views
13

あるテーブルから行を削除し、追加のデータを別のテーブルに挿入しようとしています。私はこれが2つの別々のコマンドで実行できることを知っています。削除するコマンドと新しいテーブルに挿入するコマンドです。しかし、私はそれらを結合しようとしていますし、それが動作していない、これはこれまでのところ、私のクエリです:postgresqlのINSERTにDELETEの戻り値を挿入するにはどうすればよいですか?

ERROR: syntax error at or near "delete"

誰がどのように指摘することができます:私は次のエラーを取得することを実行すると

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

それを達成するために、または良い方法がありますか?それとも不可能なのでしょうか?

答えて

4

だろう。関数は2つのステートメントよりも利点があり、常に1つのトランザクションで実行されるため、クライアントコードでトランザクションを明示的に開始およびコミットする必要はありません。

+0

私のために働く、ありがとう! – NoToBagels

0

あなたが持っている構文は無効です。 2つのステートメントがこれを実行する最善の方法です。それを行う最も直感的な方法は、最初に挿入を行い、次に削除を行うことです。

-1

"AI W"では、確かに2つのステートメントが最適ですが、トリガーを作成することも考えられます。あなたの最初のテーブルで何かが削除されるたびに、別のテーブルが埋められます。

32

まだリリースされていないPostgreSQL 9.1をリリースする前に、これを行うことはできません。

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; 
$$ 

をしてからちょうどselect move_from_a_to_b(1, 5)を使用します。そして、構文では、この(未テスト)のような揮発性関数を作成することができますPostgreSQLの9.1前

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

は、私が使用しますが、この答えのためにありがとうございましたこれは、今のところ、Tometzkyの方法で行う必要があります。 – lanrat

1

すべてのバージョンのPostgreSQLでは、テーブルから行を削除して別のテーブルに挿入するトリガ機能を作成できます。しかし、PostgreSQL 9.1でリリースされている一括挿入よりも遅いようです。古いデータを削除する前に別のテーブルに移動するだけで済みます。 PostgreSQLの9.1の後にあなたがこれを行うことができ、答えは上記のよう

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(); 

::これは、古いデータ・タイプで行われ、私は9.1に移動したときに

WITH tmp AS (DELETE FROM table RETURNING column1, column2, ...) 
    INSERT INTO another_table (column1, column2, ...) SELECT * FROM tmp; 
関連する問題