J'utilise trois instructions d'insertion, et s'il y a une erreur dans la troisième instruction, je veux annuler la première et la seconde. S'il n'y a aucun moyen de le faire, dites-moi s'il vous plaît une approche différente pour gérer cela dans PostgresqQL.
Si j'utilise COMMIT
ou ROLLBACK
, j'obtiens une erreur.
CREATE OR REPLACE FUNCTION TEST1 ()
RETURNS VOID
LANGUAGE 'plpgsql'
AS $$
BEGIN
INSERT INTO table1 VALUES (1);
INSERT INTO table1 VALUES (2);
INSERT INTO table1 VALUES ('A');
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;$$;
Le code ci-dessus ne fonctionne pas; COMMIT
et ROLLBACK
ne sont pas pris en charge par les fonctions PostgreSQL.
Par rapport aux autres langages SQL, vous devriez penser que Postgres s'occupe toujours de la validation/restauration en cas d'erreur implicite lorsque vous êtes à l'intérieur d'une transaction .
Voici ce que le doc dit:
Les transactions sont un concept fondamental de tous les systèmes de bases de données. Le point essentiel d'une transaction est qu'elle regroupe plusieurs étapes en une seule opération, tout ou rien. Les états intermédiaires entre les étapes ne sont pas visibles par les autres transactions simultanées, et si une défaillance se produit qui empêche la transaction de se terminer, aucune des étapes n'affecte la base de données.
CREATE OR REPLACE FUNCTION TEST1 ()
RETURNS VOID
LANGUAGE 'plpgsql'
AS $$
BEGIN
INSERT INTO table1 VALUES (1);
INSERT INTO table1 VALUES (2);
INSERT INTO table1 VALUES ('A');
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;$$;
Vous ne pouvez pas utiliser des instructions de transaction comme SAVEPOINT
, COMMIT
ou ROLLBACK
dans une fonction.
Le BEGIN
qui démarre un bloc dans PL/pgSQL est différent de l'instruction SQL BEGIN
qui démarre une transaction.
Supprimez simplement le COMMIT
de votre fonction, et vous avez la solution: puisque la fonction entière est toujours exécutée dans une seule transaction, toute erreur dans la troisième instruction entraînera un ROLLBACK
qui annule également les deux premières déclarations.