sql >> データベース >  >> RDS >> PostgreSQL

別のテーブルから削除されたときにPostgreSQLにテーブルに行を挿入させるにはどうすればよいですか?

    トリガー関数を記述します。このようなもの:

    CREATE OR REPLACE FUNCTION trg_backup_row()
      RETURNS trigger AS
    $BODY$
    BEGIN
    
    INSERT INTO other_tbl
    SELECT (OLD).*, t.other_col                -- all columns of from old table
    -- SELECT OLD.col1, OLD.col2, t.other_col  -- alternative: some cols from old tbl
    FROM   third_tbl t
    WHERE  t.col = OLD.col  -- link to third table with info from deleted row
    AND    <unique_condition_to_avoid_multiple_rows_if_needed>;
    
    RETURN NULL;
    
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE;
    

    そして、トリガー ON DELETE 。このように:

    CREATE TRIGGER delaft
      AFTER DELETE
      ON tbl
      FOR EACH ROW
      EXECUTE PROCEDURE trg_backup_row();
    

    重要な要素

    • トリガーAFTERDELETEにするのが最適です。 およびFOREACH ROW

    • 古いテーブルからすべての列を返すには、構文(OLD)。*を使用します。 。 複合型へのアクセス に関するマニュアルを参照してください。 。または、OLD。* OLD であるため、も有効な構文です。 FROMに追加されます 暗黙的に節。 VALUESの場合 式は(OLD)。*である必要があります 、 けれど。いいね:

      INSERT INTO other_tbl
      VALUES((OLD).*, some_variable)
      
    • 私が示すように、他のテーブルの値を含めることができます。必ず1つの行を取得するか、複数のエントリを作成してください。

    • トリガーがAFTERを起動すると イベントの場合、関数は RETURN NULLを実行できます 。

    可視性について

    @coulingの用心深いコメントに応えて。

    外部キーは DEFERRED 、これは整合性チェックのみを延期し、削除自体は延期しません。手元の行の前に実行されたトリガーで削除された行または ON DELETE CASCADEによる 外部キーは表示されなくなります このAFTERDELETEの時点で トリガーが呼び出されます。 (すべてが1つのトランザクションで発生することは明らかです。これらの詳細は他のトランザクションでは重要ではなく、すべての効果が表示されるか、まったく表示されません。MVCCモデルとトランザクションの分離 。)

    したがって、 INSERT にそのような方法で依存する行からの値を含める場合は、 、必ずこのトリガーを前に呼び出してください それらの行は削除されます。

    このトリガーをBEFOREDELETEにする必要がある場合があります 。

    または、それに応じてトリガーを並べ替える必要があることを意味する場合もあります。 BEFORE トリガーはAFTERの前にあります 明らかにトリガーします。また、同じレベルのトリガーは、アルファベット順 で実行されます。 。

    ただし、ここで非常に正確である限り、他の BEFORE の行(または依存する行)に加えられた変更を追加することもできます。 トリガーは、 beforeと呼ばれる場合にのみ表示されます。 これ。

    AFTERにするための私のアドバイス トリガーは、他のトリガーが DELETE をキャンセル(ロールバック)する可能性がある場合、合併症が発生しにくく、安価であるためです。 操作の途中-上記のいずれにも当てはまらない限り。



    1. mysql_escape_string()関数は非推奨ですmysql_real_escape_string()Codeigniterを使用してください

    2. Oracleで複数の文字列を一緒に置き換える方法

    3. Pentahoでダッシュボードを作成するときにpostgresで作成された「接続が多すぎます」

    4. 複数の列に対するMySQL全文検索:結果の混乱