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

SQL Firebird Discussion :

Problème de trigger


Sujet :

SQL Firebird

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 118
    Points : 89
    Points
    89
    Par défaut Problème de trigger
    Bonjour,

    ci dessous un trigger qui met a jour la taille du champ N_COMPTE lors de insertion en ajoutant des 0 a la fin pour avoir une chaine de n caractere defini selon le champs width de table params

    exp: si utilisateur saisi 253 dans application le champ insérer dans la table est 25300000 (si width=8 caracteres )

    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
    21
    22
    23
    24
    25
    26
    27
     
    CREATE TRIGGER NC_NCPT_WIDTH FOR C_PLAN ACTIVE BEFORE INSERT POSITION 0 AS
    DECLARE VARIABLE cptwdth integer;
    DECLARE VARIABLE ileng integer;
    DECLARE VARIABLE chaine varchar(14);
    begin
    SELECT P_N_COMPTE_WIDTH FROM C_PARAMS into :cptwdth; 
    if (:cptwdth=0) then
    BEGIN
    IF ( NEW.N_COMPTE_P IS NULL ) THEN
       NEW.N_COMPTE_P=NEW.N_COMPTE_P;
    END
    ELSE
    if (:cptwdth>1) then
     begin 
       IF ( NEW.N_COMPTE_P IS NULL ) THEN  
        BEGIN         
          ileng = CHAR_LENGTH(NEW.N_COMPTE_P);
           while (ileng<cptwdth) do  
           begin 
            chaine =  chaine||'0'; 
            ileng=ileng+1; 
           end
          NEW.N_COMPTE_P=chaine;
        END    
     end   
    end
    ou
    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
     
    CREATE TRIGGER C_CPT_WIDTH FOR C_PLAN ACTIVE BEFORE INSERT POSITION 0 AS
    DECLARE VARIABLE cptwdth integer;
    begin
    SELECT P_N_COMPTE_WIDTH FROM C_PARAMS into :cptwdth; 
    if (:cptwdth=0) then
    BEGIN
    IF ( NEW.N_COMPTE_P IS NULL ) THEN
       NEW.N_COMPTE_P=NEW.N_COMPTE_P;
    END
    ELSE
    if (:cptwdth>1) then
     begin   
       IF ( NEW.N_COMPTE_P IS NULL ) THEN  
        BEGIN    
         NEW.N_COMPTE_P=RPAD(NEW.N_COMPTE_P, :cptwdth, '0');       
        END   
     end   
    end
    après ajout dans la table C_PLAN il n'ya pas de changement dans le champ N_COMPTE

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 030
    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 030
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    plusieurs choses m'interpellent :
    1-SELECT P_N_COMPTE_WIDTH FROM C_PARAMS into :cptwdth; le cas où aucune ligne n'est trouvé ou au contraire plusieurs lignes sont récupérées n'est pas traité. D'un autre côté c'est peut être une règle mais ....

    2-au niveau du code II (car j'aime bien l'utilisation de RPAD ) il y a un hic
    lignes 8 à 10
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF ( NEW.N_COMPTE_P IS NULL ) THEN
       NEW.N_COMPTE_P=NEW.N_COMPTE_P;
    END
    si valeur=null alors valeur = null ! cela ne sert à rien

    lignes 14 à 17
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      IF ( NEW.N_COMPTE_P IS NULL ) THEN  
        BEGIN    
         NEW.N_COMPTE_P=RPAD(NEW.N_COMPTE_P, :cptwdth, '0');       
        END
    SELECT RPAD(NULL,8,0) FROM RDB$DATABASE -> NULL et non '00000000'


    Ma proposition :
    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
    CREATE TRIGGER C_CPT_WIDTH FOR C_PLAN ACTIVE BEFORE INSERT POSITION 0 AS
    DECLARE VARIABLE cptwdth integer;
    begin
    SELECT P_N_COMPTE_WIDTH FROM C_PARAMS into :cptwdth;  
    if  (cptwdth IS NULL) then cptwdth=0; -- reste le cas  "plusieurs lignes sont récupérées" une clause WHERE possible sur la table C_PARAMS ?
    if (cptwdth>=1) then
     begin 
      IF (NEW.N_COMPTE_P IS NULL) THEN
      BEGIN
       NEW.N_COMPTE_P=RPAD('0',  :cptwdth, '0'); -- 00000000 si null et cptwdth=8
      END
     ELSE BEGIN
       NEW.N_COMPTE_P=RPAD(NEW.N_COMPTE_P,  :cptwdth, '0'); -- 82530000 si '8253' et cptwdth=8
     END
    end
    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

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 118
    Points : 89
    Points
    89
    Par défaut
    Ça marche ! Merci beaucoup
    1-SELECT P_N_COMPTE_WIDTH FROM C_PARAMS ....
    c'est vrai il faut prendre tous les cas possible malgré que c'est une table de paramétrage qui doit avoir toujours une seule ligne (avec definition champ P_N_COMPTE_WIDTH D_N_COMPTE DEFAULT 0) ou D_N_COMPTE domaine avec CHECK (VALUE <15 AND VALUE >= 0)

    pour la propostion elle marche tres bien, tu a oublier d'ajouter a la fin un end
    merci

  4. #4
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 378
    Points : 19 054
    Points
    19 054
    Par défaut
    Salut à tous.

    Attention à ne pas écraser la valeur dans la colonne "N_COMPTE_P" !
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    CREATE DATABASE '..\Data\Base.fdb' page_size 4096 DEFAULT CHARACTER SET WIN1252;
     
    -- ================
    -- table 'C_PARAMS'
    -- ================
     
    CREATE TABLE C_PARAMS (
      P_N_COMPTE_WIDTH INTEGER
    );
     
    commit;
     
    -- =====================
    -- table 'C_PLAN ACTIVE'
    -- =====================
     
    CREATE TABLE C_PLAN (
      id          smallint     generated by default as identity not null primary key,
      N_COMPTE_P  varchar(20)
    );
     
    commit;
     
    -- =======
    -- Trigger
    -- =======
     
    SET TERM #;
     
    CREATE TRIGGER C_CPT_WIDTH
    FOR C_PLAN ACTIVE
    BEFORE INSERT POSITION 0
    AS
    DECLARE VARIABLE cptwdth  INTEGER;
    DECLARE VARIABLE chaine   VARCHAR(20);
    BEGIN
      SELECT COALESCE(P_N_COMPTE_WIDTH, 0)  FROM C_PARAMS  INTO :cptwdth;
      chaine = COALESCE(NEW.N_COMPTE_P, '');
      NEW.N_COMPTE_P = RPAD(:chaine, maxvalue(:cptwdth,CHAR_LENGTH(:chaine)), '0');
    END#
     
    SET TERM ;#
     
    COMMIT;
     
    -- =======
    -- Cas N°1
    -- =======
     
    INSERT INTO C_PARAMS (P_N_COMPTE_WIDTH) VALUES (NULL);
    select * from C_PARAMS;
     
    P_N_COMPTE_WIDTH
    ================
              <null>
     
     
    INSERT INTO C_PLAN (N_COMPTE_P) VALUES ('25');
    select * from C_PLAN;
     
         ID N_COMPTE_P
    ======= ====================
          1 25
     
     
    -- =======
    -- Cas N°2
    -- =======
     
    update C_PARAMS set P_N_COMPTE_WIDTH = 8;
    select * from C_PARAMS;
     
    P_N_COMPTE_WIDTH
    ================
                   8
     
     
    INSERT INTO C_PLAN (N_COMPTE_P) VALUES ('3333333333');
    select * from C_PLAN;
     
         ID N_COMPTE_P
    ======= ====================
          1 25
          2 3333333333
     
     
    -- =======
    -- Cas N°3
    -- =======
     
    INSERT INTO C_PLAN (N_COMPTE_P) VALUES ('66');
    select * from C_PLAN;
     
         ID N_COMPTE_P
    ======= ====================
          1 25
          2 3333333333
          3 66000000
     
    exit;
     
    Appuyez sur une touche pour continuer...
    J'ai testé trois cas de figures :
    1) taille à zéro. Autrement dit, on ne modifie pas le contenue de la colonne "N_COMPTE_P".
    2) taille à 8 mais chaîne de caractères plus grande : on ne modifie pas la chaîne.
    3) taille à 8 mais chaîne plus petite : on complète par des zéros.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 118
    Points : 89
    Points
    89
    Par défaut
    Artemus24, merci beaucoup pour l'optimisation de code

    1) taille à zéro. Autrement dit, on ne modifie pas le contenue de la colonne "N_COMPTE_P".
    2) taille à 8 mais chaîne de caractères plus grande : on ne modifie pas la chaîne.
    3) taille à 8 mais chaîne plus petite : on complète par des zéros.
    la taille de la chaîne de caractères saisi dans un edit est gérer par l'application donc elle ne peut pas dépassée la taille indiquée dans le paramétrage,
    par contre on peut saisir une chaîne de caractères d'une taille inférieur a la taille indiquée dans le paramétrage c'est dans ce cas qu on ajoute automatiquement des zéros a la fin par la fonction RDAP.

    merci

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

Discussions similaires

  1. PL/SQL problème sur Trigger
    Par kitsune dans le forum PL/SQL
    Réponses: 4
    Dernier message: 06/12/2005, 20h35
  2. [9i] problème avec trigger after logon
    Par Michael# dans le forum Oracle
    Réponses: 2
    Dernier message: 17/03/2005, 12h14
  3. [Interbase6] Problème de triggers
    Par emeraudes dans le forum Bases de données
    Réponses: 4
    Dernier message: 08/03/2005, 09h52
  4. [SQLPLUS] - Problème de Triggers Java
    Par farcis dans le forum Oracle
    Réponses: 7
    Dernier message: 23/12/2004, 09h21
  5. [PL/SQL] problème de trigger
    Par Chuck67 dans le forum Oracle
    Réponses: 14
    Dernier message: 09/12/2004, 23h17

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