IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

Trigger invalidant la donnée au lieu de la supprimer


Sujet :

PL/SQL Oracle

  1. #1
    Membre à l'essai
    Homme Profil pro
    Géomaticien
    Inscrit en
    Octobre 2015
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Octobre 2015
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Trigger invalidant la donnée au lieu de la supprimer
    Bonjour,

    j'essaie de de créer un trigger qui invalide la donnée au lieu de la supprimer, mais j'ai beau retourner ça dans tous les sens, je ne vois pas comment faire.

    Voici les tables concernées :
    Nom : schema_de_donnees.PNG
Affichages : 97
Taille : 57,6 Ko

    L'objectif est que si un utilisateur essaie de supprimer un objet dans TA_TABLE_1, plutôt que d'obtenir le message d'erreur lui disant que la suppression est impossible en raison d'un enregistrement fils existant (ce qu'il ne comprendra pas), le champ FID_STATUT de l'objet obtienne la valeur 358 afin d'invalider cet objet.

    J'ai pensé au code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    create or replace TRIGGER B_DXX_TEST
    BEFORE UPDATE OR DELETE ON TA_TABLE_1
    FOR EACH ROW
    DECLARE
    BEGIN
     
        BEGIN -- Ce bloc permet de bloquer la suppression de l'objet en permettant au reste du code d'être exécuté dans le bloc principal
            IF DELETING THEN
                RAISE_APPLICATION_ERROR(-20001, 'Suppression impossible, l''objet va être mis en "invalide".');
            END IF;
        END;
     
        -- Passage de l'objet en "invalide"
        :new.FID_STATUT := 358;
     
        EXCEPTION
                WHEN OTHERS THEN
                    mail.sendmail('toto@gmail.com',SQLERRM,'ERREUR TRIGGER - TA_TABLE_1','TRIGGER@gmail.com');
    END;
    Le trigger est compilé et quand je tente de supprimer l'objet depuis mon application, la suppression est empêchée et j'obtiens un mail avec mon message d'erreur.
    Par contre, le champ FID_STATUT, lui, n'est pas mis à jour et je ne comprends pas pourquoi. Quelqu'un pourrait-il éclairer ma lanterne ?

    Merci d'avance.

  2. #2
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Ce commentaire est faux

    -- Ce bloc permet de bloquer la suppression de l'objet en permettant au reste du code d'être exécuté dans le bloc principal
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            IF DELETING THEN
                RAISE_APPLICATION_ERROR(-20001, 'Suppression impossible, l''objet va être mis en "invalide".');
            END IF;
        END;
    Un RAISE_APPLICATION_ERROR va remonter l'erreur au bloc parent.. qui ne catche rien (BEGIN ... END; sans exception), donc ça remonte au bloc grand-parent qui catche

    Ce code n'est donc jamais exécuté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        -- Passage de l'objet en "invalide"
        :new.FID_STATUT := 358;
    Bloc grand-parent qui catche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        EXCEPTION
                WHEN OTHERS THEN
                    mail.sendmail('toto@gmail.com',SQLERRM,'ERREUR TRIGGER - TA_TABLE_1','TRIGGER@gmail.com');
    END;
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  3. #3
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Bonjour,
    C'est normal quand tu fais RAISE_APPLICATION_ERROR tu transmets l'exécution au gestionnaire d'erreur "le plus proche", ici c'est le bloc OTHERS, donc ta ligne de changement de statut n'est pas exécutée. Il ne faut pas faire planter le trigger si tu veux que la transaction aboutisse et donc que tes données soit commitées.

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Et pourquoi un déclencheur update or delete ?

  5. #5
    Membre émérite
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2013
    Messages
    1 993
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 1 993
    Points : 2 499
    Points
    2 499
    Par défaut
    Tu fais un trigger "BEFORE UPDATE OR DELETE".

    Ce code ne s'exécute que pour le DELETE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            IF DELETING THEN
                RAISE_APPLICATION_ERROR(-20001, '
    Ce code sera exécuté pour un DELETE et un UPDATE mais est-ce ce que tu veux?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    :new.FID_STATUT := 358;
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

  6. #6
    Membre à l'essai
    Homme Profil pro
    Géomaticien
    Inscrit en
    Octobre 2015
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Octobre 2015
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    J'avais mis BEFORE UPDATE OR DELETE parce que sinon j'obtenais une erreur, mais l'idée est qu'il ne se déclenche que pour un DELETE, donc effectivement "BEFORE DELETE" suffit.

    Merci à tous pour vos explications c'est beaucoup plus clair !
    Effectivement je faisais fausse route.

  7. #7
    Membre émérite
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2013
    Messages
    1 993
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 1 993
    Points : 2 499
    Points
    2 499
    Par défaut
    Si tu fais un BEFORE DELETE, alors pas besoin de mettre IF DELETING.
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

Discussions similaires

  1. TRIGGER/cohérence des données/perf !?
    Par Liloye dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 12/01/2012, 09h40
  2. Réponses: 6
    Dernier message: 02/05/2011, 11h29
  3. Trigger invalide - PLS-00302
    Par dbfm78 dans le forum PL/SQL
    Réponses: 1
    Dernier message: 04/02/2009, 12h49
  4. lancement procedure-trigger à une heure donnée de la journée?
    Par bibi_forever dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 16/05/2007, 15h52
  5. [Oracle 9i] Trigger base de données
    Par Herveg dans le forum Oracle
    Réponses: 7
    Dernier message: 21/12/2005, 15h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo