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 Oracle Discussion :

[8i][PL/SQL] EXECUTE IMMEDIATE


Sujet :

SQL Oracle

  1. #1
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut [8i][PL/SQL] EXECUTE IMMEDIATE
    Bien le bonjour à toutes et à tous.

    Je me pose quelques questions relatives à EXECUTE IMMEDIATE; Mon code est le 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
    31
    32
    33
    34
    DECLARE
        vRequete            VARCHAR2(300);
        vErrMajMaTable    EXCEPTION;
    BEGIN
        IF(premiere condition) THEN
            vRequete := 'INSERT INTO MaTable
                (
                    MonChamp1
                    , MonChamp2
                )
                VALUES
                (
                    '||MaVariable1||'
                    , '||MaVariable2||'
                )';
        ELSE
            vRequete := 'UPDATE MaTable
                SET 
                    MonChamp1 = '||MaVariable1||'
                    , MonChamp2 = '||MaVariable2||'
                WHERE gnagnagna ';
        END IF;
    
        EXECUTE IMMEDIATE vRequete;
    
        IF(SQL%NOTFOUND) THEN
            RAISE vErrMajMaTable;
        END IF;
    
    EXCEPTION
        WHEN vErrMajMaTable THEN
            FonctionQuiTraceErreur(prend en argument la requete);
        blablabla;
    END;
    J'ai l'erreur suivante qui pointe sur la ligne en rouge
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORA-06502 : erreur numerique ou erreur sur une valeur.
    Je ne sais pas trop où est le problème puisque j'ai bien déclaré ma variable vRequete, la longueur est bonne qui plus est.

    Bon sinon, j'ai d'autres questions concernant EXECUTE IMMEDIATE.
    - Est-ce que la requete passée en paramètre doit se terminer par un ";"
    - De quel type doit être cette variable ?

    merci d'avance

    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  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
    Pourquoi ne pas la déclarer d'entrée en Varchar(4000) ?....
    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
    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
    Citation Envoyé par Bahan
    Bon sinon, j'ai d'autres questions concernant EXECUTE IMMEDIATE.
    - Est-ce que la requete passée en paramètre doit se terminer par un ";"
    - De quel type doit être cette variable ?
    le ; final ne doit être indiqué que pour un block 'BEGIN Instruction... END ;'

    cette variable est forcément une chaine de caractères.
    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

  4. #4
    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
    de plus, je vous conseille de faire démarrer les lignes contenues dans la chaine en colonne 1.
    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

  5. #5
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Merci de votre prompte réponse.
    Cela m'a permis de faire disparaître ma première erreur.

    Cependant, une nouvelle est apparue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORA-00932 : Type de données incohérents
    Au niveau de cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE IMMEDIATE vRequete;
    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  6. #6
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Ok pour la colonne 1.
    cf mon premier post.
    Cependant, mon erreur soulevée dans mon post #5 est toujours là.

    A noter que j'avais oublié sur le forum de mettre les '|| et ||' autour de mes variables dans ma requête (mais je n'avais pas oublié de les mettre dans mon code).

    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  7. #7
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Il semblerait que tout le problème vienne de ce petit bout de code issu de ma requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'AND MonChampDate = TRUNC('||MaVariableDate||')'
    C'est certainement parce qu'il n'y a pas de " ' " qui l'encadre j'imagine. Mais comment pallier à ce problème ? Existe-t-il en PLSQL un caractère permettant de "protéger" d'autres caractères.

    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  8. #8
    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
    Pouvez-vous donc poster le code corrigé ?
    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

  9. #9
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Voici :

    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
    DECLARE
        vRequete            VARCHAR2(4000);
        vErrMajMaTable    EXCEPTION;
        vMaVariable1        NUMBER;
        vMaVariable2        DATE;
    BEGIN
        IF(premiere condition) THEN
            vRequete := 'INSERT INTO MaTable
                (
                    MonChamp1
                    , MonChamp2
                )
                VALUES
                (
                    '||vMaVariable1||'
                    , '||vMaVariable2||'
                )';
        ELSE
            vRequete := 'UPDATE MaTable
                SET 
                    MonChamp1 = '||vMaVariable1||'
                    , MonChamp2 = '||vMaVariable2||'
                WHERE gnagnagna ';
        END IF;
    
        EXECUTE IMMEDIATE vRequete;
    
        IF(SQL%NOTFOUND) THEN
            RAISE vErrMajMaTable;
        END IF;
    
    EXCEPTION
        WHEN vErrMajMaTable THEN
            FonctionQuiTraceErreur(prend en argument la requete);
        blablabla;
    END;
    Ici, MaVariable2 est une date et c'est cela qui pose problème car quand je l'enlève je n'ai plus l'erreur d'incohérence du type de données.

    Quel est le caractère de neutralisation en PLSQL ? Ce n'est pas '\', ça c'est certain

    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  10. #10
    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
    Utilisez To_Date() avec les dates

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    || ' To_date(''' || variable || ''',''DD/MM/YYYY'') ' || ' ... '
    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

  11. #11
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Donc si je reprends l'exemple de ma requête cela donnerait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    vRequete := 'UPDATE MaTable
        SET 
            MonChamp1 = '||vMaVariable1||'
            , MonChamp2 = TO_DATE('||vMaVariable2||', ''DD/MM/YYYY HH24:MI:SS'')
        WHERE gnagnagna ';
    Est-ce cela ?

    Edit : Rien à faire, j'ai toujours la même erreur qui s'affiche à propos de type de données incohérents.

    Il serait donc impossible de stocker par ce biais dans des variables des reeuêtes faisant intervenir des dates ?

    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  12. #12
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Le TO_DATE, il lui faut une chaine de caractère en entrée
    Donc il faut que tu fasses ceci (faut vérifier les cotes) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'TO_DATE(''' || to_char(v_madate, 'DD.MM.YYYY') || ''', ''DD.MM.YYYY'')';
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  13. #13
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Sinon, pour débugguer, il te suffit d'afficher ta requete par un DBMS_OUTPUT.PUT_LINE(vRequete), et ensuite tu testes cette requete.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  14. #14
    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
    Je l'ai dis des tas de fois et le répeterai sans cesse :

    lorsque vous jouez avec le SQL dynamique, sortez votre requête dans une table ou avec dbms_output afin de pouvoir la jouer sous Sql*Plus ou Sql Developer.

    S'il y a erreur, vous la découvrirez immédiatement !
    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

  15. #15
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Voila ce que cela a donné :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    vRequete := 'UPDATE MaTable
                    SET 
                        MonChamp1 = '||vMaVariable1||'
                        , MonChamp2 = TO_DATE('''||TO_CHAR(vMaVariable2)||''', ''DD/MM/YYYY HH24:MI:SS'')
                    WHERE gnagnagna ';
    A priori, cela fonctionne.

    Pendant que j'y suis, j'ai une autre question.
    Pour être certain que ma requete (insert ou update) a bien fonctionné, je faisais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF(SQL%NOTFOUND) THEN
        RAISE vErrMajMaTable;
    END IF;
    Cependant, est-ce que l'on peut faire ça après un EXECUTE IMMEDIATE ?

    lorsque vous jouez avec le SQL dynamique, sortez votre requête dans une table ou avec dbms_output afin de pouvoir la jouer sous Sql*Plus ou Sql Developer.
    Okdoki, je vais aller voir comment procéder avec dbms_output.

    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  16. #16
    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
    SQL%ROWCOUNT donne également le nombre de lignes impactées par le dernier ordre SQL.
    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

  17. #17
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    D'où ma question, un EXECUTE IMMEDIATE vRequete va lancer la requête vRequete. Est-ce que si ensuite je fais un SQL%NOTFOUND ou un SQL%ROWCOUNT avec une levée d'exception dedans, je ne vais pas forcément y aller.

    Cf mon post #15

    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  18. #18
    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
    quelle levée d'exception ?....

    SQL%ROWCOUNT donne le nombre de lignes impactées par la dernière command SQL, c'est tout !
    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

  19. #19
    Membre régulier Avatar de Bahan
    Inscrit en
    Avril 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Avril 2006
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Oups, pardon, je n'ai pas été clair.

    Voila ce que je fais dans mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ...
     
    EXECUTE IMMEDIATE vMarequete;
     
    IF(SQL%NOTFOUND) THEN
        RAISE vErrMajMaTable;
    END IF;
    je teste la valeur de SQL%NOTFOUND. Et en fait ma question est : est-ce que, après un EXECUTE IMMEDIATE maRequete, le SQL%NOTFOUND prend bien "appui" sur maRequete ?

    Ou alors est-ce que le SQL%ROWCOUNT ou le SQL%NOTFOUND ne prend pas en compte le EXECUTE IMMEDIATE et donc, cela me dirigerait constamment vers l'exception que j'ai créé.

    Hum, est-ce que j'ai été plus clair ?

    -----

    Mon problème c'est que j'essaie de tester le bon fonctionnement d'une requête UPDATE ou INSERT. Donc, je fais un SQL%NOTFOUND.

    Cela marche très bien quand j'écrits directement mes requêtes dans mon code.

    Par contre,
    1. dès que je place ces requêtes dans une variable de type VARCHAR2(4000)
    2. que je fais ensuite un EXECUTE IMMEDIATE
    3. puis une boucle IF sur SQL%NOTFOUND

    J'entre forcément dans ma boucle SQL%NOTFOUND, i.e. les requêtes ne se sont pas bien passées.

    Bahan
    Bats-toi de toutes tes forces tant que tu es en vie, et n'abandonne que quand tu es mort

  20. #20
    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
    Bon, je n'arrive plus trop à vous suivre.
    Voici un example:

    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
    SQL> set serveroutput on
    SQL> 
    SQL> DECLARE
      2    LN$COUNT PLS_INTEGER ;
      3  BEGIN
      4    UPDATE EMP SET sal = sal ;
      5    IF SQL%FOUND THEN
      6      dbms_output.put_line( '1- SQL%ROWCOUNT = ' || SQL%ROWCOUNT ) ;
      7    END IF ;
      8    ROLLBACK;
      9    EXECUTE IMMEDIATE 'UPDATE EMP SET sal = sal' ;
     10    IF SQL%FOUND THEN
     11      dbms_output.put_line( '2- SQL%ROWCOUNT = ' || SQL%ROWCOUNT ) ;
     12    END IF ;
     13    ROLLBACK;
     14    EXECUTE IMMEDIATE 'UPDATE EMP SET sal = sal where 1 = 2' ;
     15    IF SQL%FOUND THEN
     16      dbms_output.put_line( '3- SQL%ROWCOUNT = ' || SQL%ROWCOUNT ) ;
     17    END IF ;
     18    ROLLBACK;    
     19  END;
     20  /
    1- SQL%ROWCOUNT = 14
    2- SQL%ROWCOUNT = 14
     
    Procédure PL/SQL terminée avec succès.
     
    SQL>
    la ligne 3 n'est pas imprimée parce que :
    1. SQL%FOUND vaut FALSE
    et par conséquent SQL%ROWCOUNT = 0
    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

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Oracle 9iR2][PL/SQL] EXECUTE IMMEDIATE USING
    Par mainecoon dans le forum Oracle
    Réponses: 4
    Dernier message: 08/02/2007, 19h08
  2. SQl loader et execute immediate
    Par salim_kwada dans le forum SQL*Loader
    Réponses: 2
    Dernier message: 31/08/2006, 13h30
  3. [PL/SQL] EXECUTE IMMEDIATE et INSERT et RETURNING
    Par swirtel dans le forum Oracle
    Réponses: 2
    Dernier message: 18/04/2006, 09h25
  4. [PL/SQL] Execute immediate
    Par BiM dans le forum Langage SQL
    Réponses: 7
    Dernier message: 10/08/2005, 11h13
  5. [pl/sql] execute immediate
    Par Nadine dans le forum Oracle
    Réponses: 16
    Dernier message: 23/02/2005, 17h37

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