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 :

Triggers Oracle automatisés


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Septembre 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Septembre 2014
    Messages : 8
    Par défaut Triggers Oracle automatisés
    Bonjour,

    Je travaille sur un script qui me permettrai de créer des triggers automatiques sur certaines des tables de ma base.

    Je voudrai un trigger before insert pour les tables voulues qui stocke dans une table (créée au préalable) la valeur de tous les champs de la ligne nouvellement créée.

    je ne sais pas si je suis bien clair:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE OR REPLACE TRIGGER TRI_MATABLE 
      BEFORE INSERT ON SA.MATABLE
      FOR EACH ROW
    BEGIN
      IF INSERTING THEN 
        insert into XTRIGTRC (NOMTAB,TYPFIRE,VALEURS) values ('MATABLE','I', :new.CHAMP1|| ';' || :new.CHAMP2|| ';' || :new.CHAMP3);
      END IF;
    END;
    /
    Ce trigger fonctionne: il me ramène dans VALEURS la liste des champs de ma ligne, séparées par des points virgules. C'est bien le résultat voulu.

    Mais je souhaite l'automatiser pour plusieurs tables, et je me vois mal écrire à la main la liste des champs de chaque table...

    J'avais donc pensé à la requête suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select replace(wmsys.wm_concat(':new.' || COLUMN_NAME), ',', ' || '';'' || ') COL from USER_TAB_COLUMNS where TABLE_NAME='MATABLE';
    Pour récupérer les champs de chaque table, et donc pouvoir faire quelque chose du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE OR REPLACE TRIGGER TRI_MATABLE 
      BEFORE INSERT ON SA.MATABLE
      FOR EACH ROW
    BEGIN
      IF INSERTING THEN 
        insert into XTRIGTRC (NOMTAB,TYPFIRE,VALEURS) values ('MATABLE','I', (Select replace(wmsys.wm_concat(':new.' || COLUMN_NAME), ',', ' || '';'' || ') COL from USER_TAB_COLUMNS where TABLE_NAME='MATABLE'));
      END IF;
    END;
    /
    Seulement, je n'ai pas le résultat voulu... Le champ VALEURS de la table XTRIGTRC vaut : :new.CHAMP1|| ';' || :new.CHAMP2|| ';' || :new.CHAMP3 (forcément)

    Du coup je bloque sur cette requête: comment faire pour récupérer de manière automatique les champs d'une table donnée, à l'intérieur d'un trigger ?

    Merci d'avance de votre aide.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Il faut le faire en deux étapes :
    1. créez un bloc PL/SQL qui générera le SQL du déclencheur
    2. exécutez-le

  3. #3
    Membre du Club
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Septembre 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Septembre 2014
    Messages : 8
    Par défaut
    Bonjour,

    J'ai essayé de cette façon

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    select 'CREATE OR REPLACE TRIGGER TRITNR_' || table_name || 
    ' BEFORE INSERT ON SA.' ||  table_name || 
    ' FOR EACH ROW
    BEGIN
    IF INSERTING THEN 
    insert into XTNRTRIGTRC (NOMTAB,TYPFIRE,VALEURS) values (''' || table_name  || ''',''I'', ' || (Select replace(wmsys.wm_concat(':new.' || COLUMN_NAME), ',', ' || '';'' || ') COL from USER_TAB_COLUMNS where TABLE_NAME=table_name) || ';' ||
    '
    END IF;'||
    '
    END;'||
    '
    /'
    from  dba_tables  where owner  = 'SA' and table_name = 'MA_TABLE'   ;
    Mais la requête tourne pendant très longtemps puis finie par me donner le message d'erreur suivant:

    ORA-01652: impossible d'étendre le segment temporaire de 128 dans le tablespace TEMP
    ORA-06512: à "WMSYS.WM_CONCAT_IMPL", ligne 22
    01652. 00000 - "unable to extend temp segment by %s in tablespace %s"
    *Cause: Failed to allocate an extent of the required number of blocks for
    a temporary segment in the tablespace indicated.
    *Action: Use ALTER TABLESPACE ADD DATAFILE statement to add one or more
    files to the tablespace indicated.

  4. #4
    Membre du Club
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Septembre 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Septembre 2014
    Messages : 8
    Par défaut
    Si j'essaye de me passer de "wmsys.wm_concat", et plutôt utiliser LISTAGG, j'ai encore un souci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    select 'CREATE OR REPLACE TRIGGER TRITNR_' || table_name || 
    ' BEFORE INSERT ON SA.' ||  table_name || 
    ' FOR EACH ROW
    BEGIN
    IF INSERTING THEN 
    insert into XTNRTRIGTRC (NOMTAB,TYPFIRE,VALEURS) values (''' || table_name  || ''',''I'', ' || (SELECT LISTAGG(':new.' || COLUMN_NAME, ' || '';'' || ') WITHIN GROUP (ORDER BY TABLE_NAME, COLUMN_ID) COL FROM USER_TAB_COLUMNS WHERE TABLE_NAME = table_name) || ';' ||
    '
    END IF;'||
    '
    END;'||
    '
    /'
    from  dba_tables  where owner  = 'SA' and table_name = 'MA_TABLE'   ;
    ORA-01489: résultat de concaténation de chaîne trop long
    01489. 00000 - "result of string concatenation is too long"
    *Cause: String concatenation result is more than the maximum size.
    *Action: Make sure that the result is less than the maximum size.

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Vous faites un joli produit cartésien entre DBA_TABLES et USER_TAB_COLUMNS.
    Changez ce bout de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FROM USER_TAB_COLUMNS WHERE TABLE_NAME = table_name
    Par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FROM USER_TAB_COLUMNS WHERE USER_TAB_COLUMNS.TABLE_NAME = dba_tables.table_name
    Vous devriez utiliser USER_TABLES voire ALL_TABLES plutôt que DBA_TABLES.

  6. #6
    Membre du Club
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Septembre 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Septembre 2014
    Messages : 8
    Par défaut
    En effet, cela marche beaucoup mieux comme ça.

    Merci beaucoup pour l'aide.

    Pourquoi utiliser ALL_TABLES plutôt que DBA_TABLES ?

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

Discussions similaires

  1. [pl/sql] probleme trigger oracle
    Par john123 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 06/12/2007, 19h27
  2. [PL/SQL - Trigger Oracle] Données non retournées
    Par Hug0_76 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 27/02/2007, 23h12
  3. Probleme Trigger Oracle 9i
    Par Strit83 dans le forum PL/SQL
    Réponses: 5
    Dernier message: 27/11/2006, 14h24
  4. Erreur trigger oracle
    Par djsbens dans le forum Oracle
    Réponses: 7
    Dernier message: 22/02/2006, 13h37
  5. [JDBC]Probleme avec trigger Oracle
    Par aurel89 dans le forum JDBC
    Réponses: 2
    Dernier message: 02/08/2005, 11h53

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