ROLLBACK TO SAVEPOINT syntax error at or near “TO”
-
26-02-2021 - |
Question
I am having trouble in executing the following FUNCTION in PostgreSQL
CREATE OR REPLACE FUNCTION pckg_fcvoi.supprimer_voies_plus_42c (CodeEntite text) RETURNS VOID AS $body$
DECLARE
cpt_voies_ACTIV numeric := 0;
cpt_voies_User numeric := 0;
cpt_voies_42C numeric := 0;
cpt_voies_sup numeric := 0;
/*----------------------------------------------------------------*/
/* Liste des voies non importees de 42C, susceptibles d'etre */
/* supprimees. */
/*----------------------------------------------------------------*/
cursor_VOIES_PLUS_42C CURSOR FOR
SELECT com_commune.cod_ent,
com_voie.cod_insee,
com_voie.cod_rivoli,
com_voie.lib
FROM com_voie,
com_commune
WHERE com_commune.cod_insee = com_voie.cod_insee
AND com_commune.cod_ent = CodeEntite
AND com_voie.origine_voie = 'D';
BEGIN
-- DBMS_OUTPUT.ENABLE(1000000);
SELECT COUNT(*) INTO STRICT cpt_voies_ACTIV
FROM com_voie,
com_commune
WHERE com_commune.cod_insee = com_voie.cod_insee
AND com_commune.cod_ent = CodeEntite;
SELECT COUNT(*) INTO STRICT cpt_voies_User
FROM com_voie,
com_commune
WHERE com_commune.cod_insee = com_voie.cod_insee
AND com_commune.cod_ent = CodeEntite
and com_voie.origine_voie = 'U';
SELECT COUNT(*) INTO STRICT cpt_voies_42C
FROM com_voie,
com_commune
WHERE com_commune.cod_insee = com_voie.cod_insee
AND com_commune.cod_ent = CodeEntite
and com_voie.origine_voie = 'S';
SELECT COUNT(*) INTO STRICT cpt_voies_sup
FROM com_voie,
com_commune
WHERE com_commune.cod_insee = com_voie.cod_insee
AND com_commune.cod_ent = CodeEntite
and com_voie.origine_voie = 'D';
RAISE NOTICE ' - Nombre de voies dans la base ACTIV pour % : %', CodeEntite, cpt_voies_ACTIV;
RAISE NOTICE ' - Nombre de voies utilisateur pour % : %', CodeEntite, cpt_voies_User;
RAISE NOTICE ' - Nombre de voies importees de 42C pour % : %', CodeEntite, cpt_voies_42C;
RAISE NOTICE ' - Nombre de voies supprimables pour % : %', CodeEntite, cpt_voies_sup;
/*---------------------------------------------------------------------------------------*/
/* Pour toutes les voies susceptibles d'etre supprimees */
/* dont le cod_ent est a traiter : */
/* - Supprimer la voie */
/* - si la suppression echoue */
/* alors */
/* afficher la voie est supprimable mais dossier attache */
/* sinon */
/* afficher la voie est supprimee */
/* finsi */
/*---------------------------------------------------------------------------------------*/
RAISE NOTICE 'Voies ne pouvant etre supprimees de la base ACTIV pour % :', CodeEntite;
RAISE NOTICE '---------------------------------------------------------';
cpt_voies_sup := 0;
FOR enreg_VOIES_PLUS_42C IN cursor_VOIES_PLUS_42C LOOP
BEGIN
DELETE FROM com_voie
WHERE cod_insee = enreg_VOIES_PLUS_42C.cod_insee
AND cod_rivoli = enreg_VOIES_PLUS_42C.cod_rivoli;
/* DBMS_OUTPUT.PUT_LINE('Suppression de '||enreg_VOIES_PLUS_42C.COD_ENT||';'||enreg_VOIES_PLUS_42C.COD_INSEE||';'||enreg_VOIES_PLUS_42C.COD_RIVOLI||';'||enreg_VOIES_PLUS_42C.LIB);*/
cpt_voies_sup := cpt_voies_sup + 1;
EXCEPTION
/*-----------------------------------------------------------*/
/* La suppression de la voie a echoue */
/*-----------------------------------------------------------*/
WHEN OTHERS THEN
IF position('ACTIV.FK_CORRESP_VOIE' in SQLERRM) > 0
THEN
/*-------------------------------------------------------------*/
/* La suppression de la voie a echoue : */
/* supprimer la correspondance voie-gestionnaire, puis la voie */
/*-------------------------------------------------------------*/
BEGIN
/* DBMS_OUTPUT.PUT_LINE(enreg_VOIES_PLUS_42C.COD_ENT||';'||enreg_VOIES_PLUS_42C.COD_INSEE||';'||enreg_VOIES_PLUS_42C.COD_RIVOLI||';'||enreg_VOIES_PLUS_42C.LIB||'; Declaree dans SAV_CORRESP_VOIE_GEST');*/
SAVEPOINT SP_FK_CORRESP_VOIE;
DELETE FROM sav_corresp_voie_gest
WHERE cod_insee = enreg_VOIES_PLUS_42C.cod_insee
AND cod_rivoli = enreg_VOIES_PLUS_42C.cod_rivoli;
DELETE FROM com_voie
WHERE cod_insee = enreg_VOIES_PLUS_42C.cod_insee
AND cod_rivoli = enreg_VOIES_PLUS_42C.cod_rivoli;
/* DBMS_OUTPUT.PUT_LINE('Suppression de '||enreg_VOIES_PLUS_42C.COD_ENT||';'||enreg_VOIES_PLUS_42C.COD_INSEE||';'||enreg_VOIES_PLUS_42C.COD_RIVOLI||';'||enreg_VOIES_PLUS_42C.LIB);*/
cpt_voies_sup := cpt_voies_sup + 1;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO SAVEPOINT SP_FK_CORRESP_VOIE;
END;
ELSE
/*-----------------------------------------------------------*/
/* La suppression de la voie a echoue : afficher la cause */
/*-----------------------------------------------------------*/
RAISE NOTICE '%;%;%;%;%', enreg_VOIES_PLUS_42C.COD_ENT, enreg_VOIES_PLUS_42C.COD_INSEE, enreg_VOIES_PLUS_42C.COD_RIVOLI, enreg_VOIES_PLUS_42C.LIB, SUBSTR(SQLERRM, 1, 200);
END IF;
END;
END LOOP;
RAISE NOTICE ' - Nombre de voies supprimees pour % : %', CodeEntite, cpt_voies_sup;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Exception dans pckg_fcvoi.supprimer_voies_plus_42c(%) : %, %', CodeEntite, SQLSTATE, SUBSTR(SQLERRM, 1, 100);
RAISE NOTICE 'ARRET DU TRAITEMENT !';
ROLLBACK;
END;
I am having this error
syntax error at or near "TO".
It is related to the exception block?
Any solutions?
Solution 2
Just found this :
In PL/pgSQL, when an exception is caught by an EXCEPTION clause, all database changes since the block's BEGIN are automatically rolled back. if you are translating an Oracle procedure that uses SAVEPOINT and ROLLBACK TO in this style, your task is easy: just omit the SAVEPOINT and ROLLBACK TO
source : https://www.postgresql.org/docs/10/plpgsql-porting.html.
OTHER TIPS
It looks like a PL/pgSQL syntax limitation: you can create savepoint but you cannot use 'ROLLBACK TO savepoint' statement. I have not found this limitation in the documentation although documentation says that cannot run ROLLBACK in a exception block: