Postgresql
“TO”處或附近的 ROLLBACK TO SAVEPOINT 語法錯誤
我在 PostgreSQL 中執行以下 FUNCTION 時遇到問題
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;
我有這個錯誤
“TO”處或附近的語法錯誤。
它與異常塊有關嗎?
有什麼解決辦法嗎?
剛發現這個:
在 PL/pgSQL 中,當一個異常被 EXCEPTION 子句擷取時,自塊的 BEGIN 以來的所有數據庫更改都會自動回滾。如果您正在翻譯一個以這種風格使用 SAVEPOINT 和 ROLLBACK TO 的 Oracle 過程,您的任務很簡單:只需省略 SAVEPOINT 和 ROLLBACK TO
來源:https ://www.postgresql.org/docs/10/plpgsql-porting.html 。
它看起來像 PL/pgSQL 語法限制:您可以創建保存點,但不能使用“ROLLBACK TO保存點”語句。我沒有在文件中找到這個限制,儘管文件說不能在異常塊中執行 ROLLBACK: