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 :

Execute Immediate et bind variables


Sujet :

PL/SQL Oracle

  1. #1
    Candidat au Club
    Inscrit en
    Mars 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Execute Immediate et bind variables
    Bonjour,
    Je suis dans un trigger, dans lequel un curseur me renvoie les noms de colonnes qui m'intéressent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    FETCH CUR_PK INTO LCUR_PK; 
    WHILE CUR_PK%FOUND LOOP 
      lreq := 'select to_char((:new' ||lCur_PK.column_name||')) from dual';
      execute immediate lreq into ltest;
      lpk := lpk || '--' || lTest; 
    FETCH CUR_PK INTO LCUR_PK; 
    END LOOP;
    Logiquement, Oracle refuse car il souhaite binder la valeur commençant par ":".
    Connaissez vous un moyen d'effectuer ce genre d'opération ?
    Par avance merci,
    Erwan

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 948
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 948
    Points : 5 847
    Points
    5 847
    Par défaut
    1/ Même dans un trigger une "bonne pratique" consiste à placer le code dans une procédure (incluse dans un package de préférence).

    2/ Je ne suis pas fan (et je ne suis pas le seul) de la syntaxe open fetch ..., ça c'est pour ton 1er curseur, je préfère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for c in (your query) loop 
    ... 
    end loop;
    3/ Pour le 2eme curseur, sans reprendre ton exemple, tu peux utiliser USING pour bind la variable, ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    l_query := 'select * from emp where empno = :1';
    open c for l_query using p_empno;
    où p_empno pourrait être :new (ou le paramètre de la procédure dans laquelle tu passes :new)
    USING fonctionne aussi avec EXECUTE IMMEDIATE.

    Je ne suis pas un grand spécialiste des triggers, j'espère ne pas t'induire en erreur.
    Si tu as toujours des difficultés à mettre en place ton trigger, je pense qu'un exemple complet du trigger serait préférable.

  3. #3
    Candidat au Club
    Inscrit en
    Mars 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Bonjour, et merci de votre réponse, mais il me semble que le problème n'a pas été cerné.

    1/ Je suis dans un schéma spécifique, dans lequel j'ai un trigger qui fait appel à des procédures pour générer des triggers dans un autre schéma.
    J'ai besoin des pks que je récupère dans un curseur (grâce à USER_CONS_COLUMNS), je boucle sur celles-ci pour en extraire les valeurs.

    2/ Admettons.

    3/ Ma question n'est pas celle-là.

    4/ Je récupère des NOMS de colonnes dans un trigger et je souhaite conserver leurs valeurs. Oracle ne peut interpréter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    :new.MonCurseur.NomColonne
    J'utilise alors du code dynamique avec execute immediate :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    execute immediate 'select to_char((:new.'||lCur_PK.column_name||')) from dual';
    Mais il refuse d'interpréter le :new (nouvelle valeur de la colonne nommée dans le trigger) et me demande de le binder. Ce qui n'est pas du tout ce que je souhaite faire.
    Voyez vous donc un moyen de contourner ce problème ?
    Ai-je été plus précis ?
    Merci d'avance de vos réponses,
    Cordialement,
    Erwan

  4. #4
    Candidat au Club
    Inscrit en
    Mars 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Re-bonjour,

    J'ai trouvé une solution en bouclant depuis le trigger générant les triggers.
    Quelque chose qui ressemble en résumé à :

    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
     
      CURSOR CUR_PK (tTable IN TABLES_TO_AUDIT.TABLE_NAME%TYPE)IS
      SELECT 'TO_CHAR(:new.' || column_name || ');' SavPK
      FROM USER_CONS_COLUMNS WHERE CONSTRAINT_NAME in (SELECT INDEX_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME = upper(''||tTable||'') AND CONSTRAINT_TYPE = 'P')
      ORDER BY POSITION ASC; 
     
      OPEN CUR_PK(:NEW.TABLE_NAME);
      FETCH CUR_PK INTO LCUR_PK;
      tTriggerPK := 'lPk := ' || LCUR_PK.SavPK || CHR(10) ;
      FETCH CUR_PK INTO LCUR_PK;  
      WHILE CUR_PK%FOUND LOOP
        tTriggerPK := tTriggerPK || 'lPk := lPk || ''-'' || ' || LCUR_PK.SavPK || CHR(10) ;
        FETCH CUR_PK INTO LCUR_PK;
      END LOOP;
      CLOSE CUR_PK;
    Pour ensuite générer le code des triggers appropriés.
    Merci

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

Discussions similaires

  1. [9i] Variable CHAR dans EXECUTE IMMEDIATE
    Par Filippo dans le forum PL/SQL
    Réponses: 9
    Dernier message: 21/08/2013, 19h55
  2. Réponses: 4
    Dernier message: 29/10/2009, 14h25
  3. execute immediate into -une variable- ?
    Par betty33 dans le forum SQL
    Réponses: 8
    Dernier message: 19/03/2008, 13h34
  4. Bind variables et plan d'execution
    Par Wurlitzer dans le forum Oracle
    Réponses: 6
    Dernier message: 26/02/2007, 14h04
  5. Execute immediate et nom reserves
    Par nuke_y dans le forum Oracle
    Réponses: 3
    Dernier message: 22/11/2004, 18h17

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