web-dev-qa-db-ja.com

PostgreSQLの更新後と更新前の違いは何ですか

PostgreSQLの更新後と更新前の違いは何ですか? after updatebefore updateの違いを理解できませんでした。更新前に関数が常に実行されているようです。

だから私は次の例を作りました:

ステータスがtypingのときにテーブルを更新する関数を作成しましたが、10秒の遅延があります。

CREATE OR REPLACE FUNCTION fai_prueba()
  RETURNS trigger AS
$BODY$
begin
    if new.status = 'Typing' then
        update image set status = 'ToTyping', path = 'Real path' from pg_sleep(5) where id = old.id;
    end if;
    return null;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION fai_prueba()
  OWNER TO postgres;

それから私は次のトリガーを持っています

create trigger tai 
after update on image 
for each row execute procedure fai_prueba();

しかし、UPDATEを実行すると、クエリは遅延が終了するまで終了しません

UPDATE image 
    SET  path='fake path'
       , status= 'Typing' 
WHERE id=5;

>Query returned successfully: 0 rows affected, 10042 ms execution time.

それで、更新クエリがトリガーの前に終了する可能性はありますか?

8
oriaj

AFTERのトリガーとBEFORE ..のトリガーの主な違いは1つありますが、両方とも実行されます。

BEFOREトリガーでは、DMLステートメントが実行される前にトリガーが実行されます。したがって、:NEW(DELETEの場合は古い:OLD)行を変更する機会がありますBEFORE挿入/更新/削除...しかし、あなたがやりたいことは何でもできます(別のテーブルのデータをチェックして、そのテーブルの更新/挿入/何でも発行するなど)。何らかの理由でトリガーによってEXCEPTIONが発生すると、実行が停止し、DMLステートメントが実行されることはありません。

AFTERトリガーでは、DMLステートメントが実行された後にトリガーが実行されます。 :NEWおよび:OLDレコードを変更する機能をすでに失っており、実際にはそれが何かを意味しています。ただし、トリガーで必要なことは何でも実行できます。トリガーによって例外が発生した場合、PostgreSQLでは、元のDMLがロールバックされます。これがすべてのRDBMSに当てはまるとは思いませんが、現在、例を見つけるのに苦労しています。

BEFOREトリガーの一般的な用途は、データが挿入される前にタイムスタンプ列を「今」に設定することです。

AFTERトリガーの一般的な用途は、監査/履歴テーブルに変更を取り込むことです。

どちらの場合でも、例外が発生した場合は通常 ROLLBACKを発行します。

8
Joishi Bodio