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?

Was it helpful?

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:

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top