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

Oracle Discussion :

EXECUTE IMMEDIATE pas exécuté immédiatement


Sujet :

Oracle

  1. #1
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2005
    Messages
    250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 250
    Points : 277
    Points
    277
    Par défaut EXECUTE IMMEDIATE pas exécuté immédiatement
    Cela fait quelque temps que je me pose une question par rapport à un fait que j' ai constaté.
    Prenons le code suivant:
    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
     
    declare
    i number;
    begin
      select  count(*)
      into i
      from user_tables
      where table_name = 'RATE_RC_BKP';
      if i=0
      then
        execute immediate
        'create table rate_rc_bkp as '||
        'select * from rate_rc '||
        'where active_date = ''01/01/2075'' '||
        'and rate_class > 30705 '||
        'and class_of_service_code between 3321 and 3332';
     
        update rate_rc_bkp
        set active_date = '01/01/1975';
     
        delete rate_rc
        where active_date = '01/01/2075'
        and rate_class>30705
        and class_of_service_code between 3321 and 3332;
     
        commit;
     
      end if;
    end;
    /
    Si je l'exécute dans un .sql sous Unix il me renvoie l'erreur suivante:
    la table Rate_rc_bkp n'existe pas...

    pour que çà marche, il faut que j'utilise ce code ci:
    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
     
    declare
    i number;
    begin
      select  count(*)
      into i
      from user_tables
      where table_name = 'RATE_RC_BKP';
      if i=0
      then
        execute immediate
        'create table rate_rc_bkp as '||
        'select * from rate_rc '||
        'where active_date = ''01/01/2075'' '||
        'and rate_class > 30705 '||
        'and class_of_service_code between 3321 and 3332';
      end if;
    end;
    /
     
    update rate_rc_bkp
    set active_date = '01/01/1975';
    delete rate_rc
    where active_date = '01/01/2075'
    and rate_class>30705
    and class_of_service_code between 3321 and 3332;
    commit;
    /
    Et là plus de soucis de table inexistante.

    Pourquoi donc ce EXECUTE IMMEDIATE n'est il pas pris en compte immédiatement???

    Pour info je suis en 9.2 et Oracle est instrallé sur Solaris 2.6
    Dyvim

  2. #2
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    L'objet ne sera créé qu'à l'exécution. Il est donc normal que le compilateur plante lorsque vous voulez manipuler un objet qui n'existe pas encore.
    Rédacteur Oracle (Oracle ACE)
    Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
    Je ne réponds pas aux questions techniques par MP
    Blogs: Forms-PL/SQL-J2EE - Forms Java Beans

  3. #3
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2005
    Messages
    250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 250
    Points : 277
    Points
    277
    Par défaut
    Merci...

    C'était tellement évident que je n'y avais même pas pensé.

    Donc pour éviter ce problème il faut ne faire que des "execute immediate" qui ne seront pas compilés ou faire comme je fais et attendre l'éxécution du bloc PL.

    A moins qu'il n'y ait un moyen de forcer la compilation?

    Je me demandes d'ailleurs bien pourquoi les ordres de création ou d'altération de tables ne peuvent pas être éxécutés directement en PL/SQL. Cela pourrait être utile et le PL existe depuis maintenat bien longtemps mais cette fonctionalié n'a jamais été présente autrement que par le PL/SQL dynamique.
    Dyvim

  4. #4
    Membre éclairé Avatar de plabrevo
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 547
    Points : 670
    Points
    670
    Par défaut
    Citation Envoyé par dyvim
    A moins qu'il n'y ait un moyen de forcer la compilation?
    J'ai bien peu que cela soit au-dela des capacites d'un compilateur. Comment pourrait-il interpreter le code source suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    DECLARE 
    l_tab   VARCHAR2(30);
    BEGIN
    l_tab := sysdate;
    EXECUTE IMMEDIATE 'CREATE TABLE "'||l_tab||'" (n NUMBER)';
    END;
    /
    Une remarque en passant. Une syntaxe telle que la suivante est a eviter car elle ne fonctionnera correctement qu'avec un contexte NLS particulier. La bonne methode consiste a utiliser TO_DATE et de specifier explicitement le format DD/MM/YYYY
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         set active_date = '01/01/1975';

  5. #5
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2005
    Messages
    250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 250
    Points : 277
    Points
    277
    Par défaut
    Citation Envoyé par plabrevo
    Une remarque en passant. Une syntaxe telle que la suivante est a eviter car elle ne fonctionnera correctement qu'avec un contexte NLS particulier. La bonne methode consiste a utiliser TO_DATE et de specifier explicitement le format DD/MM/YYYY
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         set active_date = '01/01/1975';
    Merci de me le signaler et effectivement je n'utiliserais pas ce genre de code dans une procédure stockée.
    Mais là il s'agit d'un script "one-shot" qui vise à corriger des données mal entrées dans la base ('01/01/2075' au lieu de '01/01/1975' )
    Dyvim

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

Discussions similaires

  1. [11g] UPDATE en EXECUTE IMMEDIATE ne s'effectue pas
    Par dumas.blr dans le forum PL/SQL
    Réponses: 7
    Dernier message: 09/12/2013, 16h12
  2. execute immediate ne fonctionne pas
    Par goute dans le forum Débuter
    Réponses: 2
    Dernier message: 31/08/2009, 09h43
  3. Réponses: 4
    Dernier message: 11/10/2007, 08h51
  4. [pl/sql] execute immediate
    Par Nadine dans le forum Oracle
    Réponses: 16
    Dernier message: 23/02/2005, 17h37
  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