23

あるテーブルから行を削除し、追加データとともに別のテーブルに挿入しようとしています。これは、削除するコマンドと新しいテーブルに挿入するコマンドの 2 つの別々のコマンドで実行できることを知っています。ただし、それらを結合しようとしていますが、機能していません。これまでのクエリは次のとおりです。

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

それを実行すると、次のエラーが表示されます。

エラー: "delete" またはその付近で構文エラーが発生しました

誰かがこれを達成する方法を指摘できますか、それともより良い方法がありますか? またはそれは不可能ですか?

4

5 に答える 5

63

まだリリースされていない 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;
于 2011-07-05T06:31:16.113 に答える
8

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)。関数には、常に単一のトランザクションで実行されるという 2 つのステートメントよりも利点があります。クライアント コードで明示的にトランザクションを開始してコミットする必要はありません。

于 2011-07-05T16:01:50.513 に答える
1

すべてのバージョンの PostgreSQL で、テーブルから行を削除して別のテーブルに挿入するためのトリガー関数を作成できます。しかし、PostgreSQL 9.1 でリリースされた一括挿入よりも遅いようです。削除する前に、古いデータを別のテーブルに移動するだけです。これは、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();

上記の回答のように、PostgreSQL 9.1 以降ではこれを行うことができます。

WITH tmp AS (DELETE FROM table RETURNING column1, column2, ...)
    INSERT INTO another_table (column1, column2, ...) SELECT * FROM tmp;
于 2013-07-23T09:33:40.110 に答える
-1

「AIW」として、2つのステートメントが確かに最適なオプションですが、そのためのトリガーを作成することも検討できます。最初のテーブルで何かが削除されるたびに、別のテーブルが埋められます。

于 2011-07-05T06:03:23.990 に答える
-1

そこにある構文は有効ではありません。これを行うには、2 つのステートメントが最適です。これを行う最も直感的な方法は、挿入を最初に行い、次に削除を行うことです。

于 2011-07-05T03:57:47.627 に答える