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

Firebird Discussion :

Problème avec les PS et Triggers


Sujet :

Firebird

  1. #1
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2006
    Messages : 249
    Points : 165
    Points
    165
    Par défaut Problème avec les PS et Triggers
    Bonjour tout le monde;
    Je n'ai pas compris ce qui se passe!
    J'ai un trigger MDF_VEHICULE et je veux le désactiver lors de l'exédution d'une procédure stocké P puis je le réactive à la fin.
    Dans le corps de P, j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    DECLARE VARIABLE STMT VARCHAR(150);
    BEGIN
    STMT = 'ALTER TRIGGER MDF_VEHICULE INACTIVE'
    EXECUTE STATEMENT :STMT;
    ...
    STMT = 'ALTER TRIGGER MDF_VEHICULE ACTIVE'
    EXECUTE STATEMENT :STMT;
    mais ça ne marche pas, cad que le trigger s'exécute comme si la ligne de désactivation dans P n'existait pas.
    mais si j'exécute la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ALTER TRIGGER MDF_VEHICULE INACTIVE
    il se désactive.
    J'ai essayé de déboguer la procédure stockée dans EMS et je trouve qu'à la ligne : EXECUTE STATEMENT :STMT;
    il déclenche une erreur me disant qu'il est impossible de préparer la query car le statement est vide
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Can't Prepare , because  query is emptySQL Code: 37
    IB Error Number: 0
    Deux personnes n'apprennent pas, un arrogant et un timide.

  2. #2
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2006
    Messages : 249
    Points : 165
    Points
    165
    Par défaut
    Je l'ai trouvé après une nuit blanche
    Il suffit de faire suspend après l'exécution du statement; je ne sais pas pourquoi;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DECLARE VARIABLE STMT VARCHAR(150); 
    BEGIN 
    STMT = 'ALTER TRIGGER MDF_VEHICULE INACTIVE' ;
    EXECUTE STATEMENT :STMT;
    SUSPEND;
    Deux personnes n'apprennent pas, un arrogant et un timide.

  3. #3
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2006
    Messages : 249
    Points : 165
    Points
    165
    Par défaut
    En réalité rien n'est résolut;
    Le "suspend" faisait le rôle de "exit" de la procédure stockée sans exécuter les lignes après.
    Deux personnes n'apprennent pas, un arrogant et un timide.

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonjour , essayez avec COMMIT plutôt que suspend ;

    perso , j'ai toujours utiliser la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Desactiver 
    UPDATE RDB$TRIGGERS T SET RDB$TRIGGER_INACTIVE = 1 WHERE  T.RDB$TRIGGER_NAME=NOM_PROCEDURE
    Reactiver
    UPDATE RDB$TRIGGERS T SET RDB$TRIGGER_INACTIVE = 0 WHERE T.RDB$TRIGGER_NAME=NOM_PROCEDURE
    je ne connaissais/me rappelais pas le ACTIVE/INACTIVE , chouette j'ai (ré-)appris quelque-chose , il faut dire que j'utilise rarement le activer/désactiver et dans ce cas c'est généralement pour tous les triggers non système !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHERE T.RDB$SYSTEM_FLAG = 0
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 245
    Points : 534
    Points
    534
    Par défaut
    Bonjour,

    Il me semble que la méthode consistant à activer/désactiver des triggers de cette façon devrait être réservée à quelques cas particuliers, car elle ne peut être pratiquée que par le SYSDBA ou le propriétaire de la base. De plus elle n'est pas sans danger en environnement multi-utilisateurs.
    Quand c'est nécessaire, je préfère utiliser un variable d'environnement par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select rdb$set_context('USER_TRANSACTION','INACTIVE_TRIGGER','1') from rdb$database
    pour la positionner, puis
    select rdb$set_context('USER_TRANSACTION','INACTIVE_TRIGGER',null) from rdb$database
    pour la supprimer
    et dans les triggers concernés, tester l'existence de cette variable avant d'exécuter le code.
    L'utilisateur n'a ainsi pas besoin de droits particuliers et lui seul est concerné par cette modification dans l'exécution d'un trigger.

    André

  6. #6
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2006
    Messages : 249
    Points : 165
    Points
    165
    Par défaut
    Merci Sergio;
    Même ta méthode ne marche pas cad :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    UPDATE RDB$TRIGGERS SET RDB$TRIGGER_INACTIVE = 1 WHERE  RDB$TRIGGER_NAME='MDF_VEHICULE';
    le trigger fonctionne comme si je n'est rien écris.
    Alors pour le commit à la place de suspend le commit est pour les transaction pas pour les procédures.
    pour André, je n'ai pas compris comment utiliser les variables, où est ce que je précise le nom du trigger à désactiver?
    Deux personnes n'apprennent pas, un arrogant et un timide.

  7. #7
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Alors pour le commit à la place de suspend le commit est pour les transaction pas pour les procédures
    tout à fait , mais une procédure est une transaction en soit,(le UPDATE ou le ALTER devrait être 'Commité' , alors , avant de dire que cela ne fonctionnera pas , il faudrait peut être l'essayer ?

    Nota : un SUSPEND est pour renvoyer des résultats

    Il me semble que la méthode consistant à activer/désactiver des triggers de cette façon devrait être réservée à quelques cas particuliers, car elle ne peut être pratiquée que par le SYSDBA ou le propriétaire de la base. De plus elle n'est pas sans danger en environnement multi-utilisateurs.
    absolument
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  8. #8
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2006
    Messages : 249
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    alors , avant de dire que cela ne fonctionnera pas , il faudrait peut être l'essayer ?
    absolument
    Mais je l'ai essayé avant de le dire
    Deux personnes n'apprennent pas, un arrogant et un timide.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 245
    Points : 534
    Points
    534
    Par défaut
    Citation Envoyé par kaouane Voir le message
    pour André, je n'ai pas compris comment utiliser les variables, où est ce que je précise le nom du trigger à désactiver?
    1- L'utilisation de rdb$get_context et rdb$set_context est bien expliquée http://www.firebirdsql.org/file/docu...grefupd25.html
    2- Ce n'est pas la variable elle même qui active ou désactive un trigger, mais en testant sa valeur ou son existence dans le code du trigger on peut définir quelle partie du code sera ou non exécutée.

    André

  10. #10
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2006
    Messages : 249
    Points : 165
    Points
    165
    Par défaut
    Voila ce que m'a dit l'équipe Firebird :
    It's not going to work because every DDL (including activating/disactivating indices) is actually executed on commit, so you cannot do it in the middle of transaction. That said, I suppose you could workaround that using an autonomous transaction.;
    Cela veut dire que mon idée ne marche pas comme voulu, mais je doit désactiver le trigger et l'activer en dehors de la PS.
    Deux personnes n'apprennent pas, un arrogant et un timide.

  11. #11
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2006
    Messages : 249
    Points : 165
    Points
    165
    Par défaut
    Une très bonne solution pour réaliser ce que je voulais faire c'est l'utilisation des variable comme a proposé André (merci pour lui). Au début de la PS j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     RDB$SET_CONTEXT(''USER_SESSION'',''PROCEDURE'',1); ....
    et à la fin je mais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ... RDB$SET_CONTEXT(''USER_SESSION'',''PROCEDURE'',0);
    et dans le trigger je mais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     IF (rdb$get_context(''USER_SESSION'', ''PROCEDURE'')=0) THEN     INSERT INTO JOURNAL ("UTILISATEUR","DATE","TIME") ...............
    le tigger n'est éxécuté qu'en dehors de la procédure et aussi sans aucune crainte dans un environnement multi utilisateurs. Et ça marche très bien. Merci pour tout le monde et spécialement pour Sergio et André
    Deux personnes n'apprennent pas, un arrogant et un timide.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 245
    Points : 534
    Points
    534
    Par défaut
    Cà m'étonnerai que çà marche correctement comme cela.
    La variable contextuelle est une chaîne de caractères. Tester sur l'existence de la valeur "0" dans le trigger, implique que la procédure ait au moins été exécutée une fois avant pour placer cette valeur.
    C'est bien pour çà que dans mes messages précédents, je mets la variable à NULL en fin de procédure, et que je parle de tester "l'existence" dans le trigger.
    Il n'est dans ce cas pas indispensable de mettre cette valeur dans le contexte de la session, celui de la transaction est suffisant et plus sûr en cas de problème au cours de l'exécution.
    André

  13. #13
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2006
    Messages : 249
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par alanglet Voir le message
    Cà m'étonnerai que çà marche correctement comme cela.
    Je te rassure que ça marche très bien;
    Citation Envoyé par alanglet Voir le message
    La variable contextuelle est une chaîne de caractères. Tester sur l'existence de la valeur "0" dans le trigger, implique que la procédure ait au moins été exécutée une fois avant pour placer cette valeur.
    La valeur de la variable contextuelle n'est pas une chaine de caractère mais de n'importe quelle velaur : http://www.firebirdsql.org/refdocs/l...t-context.html L'enchainement de l'exécution est le suivant :
    1. La PS démarre ;
    2. La valeur de la variable contex est modifié à 1 ;
    3. Les tables concernées par les trigger sont modifiés ;
    4. Les trigger sont déclencher, mais comme la valeur de la variable contex ne vérifie pas la condition du trigger, on sort sans l'exécuter ;
    5. A la fin de la PS la valeur de la var context est remis à la valeur général permettant l'exécution des trigger ;
    Et ça marche comme prévu
    Deux personnes n'apprennent pas, un arrogant et un timide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème avec les trigger delete
    Par mb10 dans le forum Administration
    Réponses: 3
    Dernier message: 25/01/2012, 16h46
  2. problème avec les triggers
    Par aldama dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 19/02/2009, 12h04
  3. problème avec les triggers
    Par jakcam dans le forum Administration
    Réponses: 4
    Dernier message: 04/03/2008, 11h37
  4. Réponses: 4
    Dernier message: 01/05/2006, 22h53
  5. []Problème avec les formulaires Outlook
    Par davidinfo dans le forum Outlook
    Réponses: 6
    Dernier message: 05/12/2002, 09h59

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