Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 13 sur 13
  1. #1
    Membre habitué
    Inscrit en
    mai 2006
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : mai 2006
    Messages : 241
    Points : 119
    Points
    119

    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 :
    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 :
    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 :
    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
    241
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : mai 2006
    Messages : 241
    Points : 119
    Points
    119

    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 :
    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
    241
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : mai 2006
    Messages : 241
    Points : 119
    Points
    119

    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 Serge Girard
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    5 270
    Détails du profil
    Informations personnelles :
    Nom : Homme Serge Girard
    Âge : 58
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 5 270
    Points : 9 613
    Points
    9 613

    Par défaut

    Bonjour , essayez avec COMMIT plutôt que suspend ;

    perso , j'ai toujours utiliser la méthode
    Code :
    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 :
    1
    2
     
    WHERE T.RDB$SYSTEM_FLAG = 0
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
    J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
    Si votre seul outil est un marteau, vous aurez tendance a ne voir que des clous

  5. #5
    Membre habitué
    Profil pro André Langlet
    Inscrit en
    avril 2010
    Messages
    70
    Détails du profil
    Informations personnelles :
    Nom : André Langlet

    Informations forums :
    Inscription : avril 2010
    Messages : 70
    Points : 115
    Points
    115

    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 :
    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
    241
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : mai 2006
    Messages : 241
    Points : 119
    Points
    119

    Par défaut

    Merci Sergio;
    Même ta méthode ne marche pas cad :
    Code :
    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 Serge Girard
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    5 270
    Détails du profil
    Informations personnelles :
    Nom : Homme Serge Girard
    Âge : 58
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 5 270
    Points : 9 613
    Points
    9 613

    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
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
    J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
    Si votre seul outil est un marteau, vous aurez tendance a ne voir que des clous

  8. #8
    Membre habitué
    Inscrit en
    mai 2006
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : mai 2006
    Messages : 241
    Points : 119
    Points
    119

    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 habitué
    Profil pro André Langlet
    Inscrit en
    avril 2010
    Messages
    70
    Détails du profil
    Informations personnelles :
    Nom : André Langlet

    Informations forums :
    Inscription : avril 2010
    Messages : 70
    Points : 115
    Points
    115

    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
    241
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : mai 2006
    Messages : 241
    Points : 119
    Points
    119

    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
    241
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : mai 2006
    Messages : 241
    Points : 119
    Points
    119

    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 :
     RDB$SET_CONTEXT(''USER_SESSION'',''PROCEDURE'',1); ....
    et à la fin je mais :
    Code :
     ... RDB$SET_CONTEXT(''USER_SESSION'',''PROCEDURE'',0);
    et dans le trigger je mais :
    Code :
     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 habitué
    Profil pro André Langlet
    Inscrit en
    avril 2010
    Messages
    70
    Détails du profil
    Informations personnelles :
    Nom : André Langlet

    Informations forums :
    Inscription : avril 2010
    Messages : 70
    Points : 115
    Points
    115

    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
    241
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : mai 2006
    Messages : 241
    Points : 119
    Points
    119

    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.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •