web-dev-qa-db-fra.com

Quelle est la différence entre une mise à jour après et une mise à jour avant dans PostgreSQL

Quelle est la différence entre une mise à jour après et une mise à jour avant dans PostgreSQL? Je ne pouvais pas comprendre la différence entre after update et before update car il semble que la fonction a toujours été exécutée avant la mise à jour.

J'ai donc fait l'exemple suivant:

J'ai créé une fonction qui met à jour une table lorsque l'état est typing mais avec un délai de 10 secondes.

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;

alors j'ai le déclencheur suivant

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

mais lorsque j'exécute une MISE À JOUR, la requête ne se termine pas avant la fin du délai

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

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

Est-il donc possible que la requête de mise à jour se termine avant le déclencheur?

8
oriaj

Il y a une différence principale entre un déclencheur APRÈS et celui AVANT .. mais les deux sont exécutés malgré tout.

Dans un déclencheur BEFORE, le déclencheur est exécuté AVANT l'exécution de l'instruction DML. Vous avez donc la possibilité de modifier la ligne: NEW (old: OLD en cas de DELETE) BEFORE c'est inséré/mis à jour/supprimé ... Mais tout ce que vous voulez faire, vous pouvez le faire (comme vérifier les données dans un tableau séparé et émettre une mise à jour/insérer/quoi que ce soit dans ce tableau, etc.). Si, pour une raison quelconque, le déclencheur provoque une EXCEPTION, l'exécution cesse et l'instruction DML n'est jamais exécutée.

Dans un déclencheur AFTER, le déclencheur est exécuté APRÈS l'exécution de l'instruction DML. Vous avez déjà perdu la possibilité de modifier les enregistrements: NEW et: OLD et que cela signifie réellement n'importe quoi. Cependant, vous pouvez toujours faire ce que vous voulez dans le déclencheur. Si le déclencheur provoque une exception, pour PostgreSQL, cela entraînera une restauration du DML d'origine. Je ne crois pas que cela soit vrai pour tous les SGBDR - mais j'ai du mal à trouver un exemple en ce moment.

Une utilisation courante d'un déclencheur BEFORE consiste à définir une colonne d'horodatage sur "maintenant" avant l'insertion des données.

Une utilisation courante d'un déclencheur AFTER consiste à remplir un tableau d'audit/historique avec les modifications.

Dans les deux cas, vous voudriez généralement vouloir émettre un ROLLBACK si vous trouvez qu'une exception a été déclenchée.

8
Joishi Bodio