PostgreSQL 中的更新后和更新前有什么区别

ori*_*iaj 14 postgresql trigger functions

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;
Run Code Online (Sandbox Code Playgroud)

然后我有以下触发器

create trigger tai 
after update on image 
for each row execute procedure fai_prueba();
Run Code Online (Sandbox Code Playgroud)

但是当我运行 UPDATE 时,查询不会结束,直到延迟结束

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

>Query returned successfully: 0 rows affected, 10042 ms execution time.
Run Code Online (Sandbox Code Playgroud)

那么有没有可能更新查询在触发器之前结束呢?

Joi*_*dio 13

触发器中的一个主要区别是 AFTER 与一个 BEFORE .. 但无论如何都会执行。

在 BEFORE 触发器中,触发器在执行 DML 语句之前执行.. 所以你有机会修改 :NEW (old :OLD in case of DELETE) 行BEFORE它被插入/更新/删除......但是任何你想要的你可以做的事情(比如检查单独表中的数据并在该表中发出更新/插入/任何内容等)。如果由于某种原因,触发器导致 EXCEPTION,则执行停止并且 DML 语句永远不会执行。

在 AFTER 触发器中,触发器在执行 DML 语句之后执行。您已经失去了修改 :NEW 和 :OLD 记录的任何能力,并使其实际上具有任何意义。但是,您仍然可以在触发器中执行任何操作。如果触发器导致异常,对于 PostgreSQL,这将导致原始 DML 的回滚。我不相信这适用于所有 RDBMS - 但我现在很难找到一个例子。

BEFORE 触发器的一个常见用途是在插入数据之前将时间戳列设置为“现在”。

AFTER 触发器的一个常见用途是用更改填充审计/历史记录表。

在任何一种情况下,如果您发现已引发异常,您通常希望发出 ROLLBACK。