Discussion: Problème de trigger

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : janvier 2007
    Messages : 113
    Points : 86
    Points
    86

    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
    Inscrit en
    janvier 2007
    Messages
    8 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 8 444
    Points : 19 725
    Points
    19 725
    Billets dans le blog
    4

    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
    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

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : janvier 2007
    Messages : 113
    Points : 86
    Points
    86

    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 Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    février 2011
    Messages
    2 933
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    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 : 2 933
    Points : 8 602
    Points
    8 602

    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
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : janvier 2007
    Messages : 113
    Points : 86
    Points
    86

    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, 21h35
  2. [9i] problème avec trigger after logon
    Par Michael# dans le forum Oracle
    Réponses: 2
    Dernier message: 17/03/2005, 13h14
  3. [Interbase6] Problème de triggers
    Par emeraudes dans le forum Bases de données
    Réponses: 4
    Dernier message: 08/03/2005, 10h52
  4. [SQLPLUS] - Problème de Triggers Java
    Par farcis dans le forum Oracle
    Réponses: 7
    Dernier message: 23/12/2004, 10h21
  5. [PL/SQL] problème de trigger
    Par Chuck67 dans le forum Oracle
    Réponses: 14
    Dernier message: 10/12/2004, 00h17

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