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 :

Appel d'un curseur sur une table pas encore créée


Sujet :

PL/SQL Oracle

  1. #1
    Candidat au Club
    Inscrit en
    Décembre 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 8
    Points : 2
    Points
    2
    Par défaut Appel d'un curseur sur une table pas encore créée
    Bonjour,

    le problème est le suivant : j'ai un script PL/SQL qui permet d'alimenter une table depuis une autre. Dans ce script, une procédure crée une table temporaire et l'alimente avec les données sources. Ensuite je dois parcourir cette table pour alimenter la cible (boucle LOOP avec des INSERT). La table temporaire est détruite à la fin du script.

    Au lancement du script donc, la table temporaire n'existe pas. Et donc le curseur qui pointe dessus pose problème et j'ai l'erreur TABLE INEXISTANTE au lancement.

    J'ai d'abord déclaré le curseur dans le DECLARE. Puis aussi après la procédure avec la syntaxe suivante pour ruser un peu mais le problème est identique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FOR record IN (SELECT * FROM TMP_MA_TABLE) LOOP
          INSERT ... ;
       END LOOP;
    Si je force la création de la table temporaire au début du script c'est pareil aussi.

    Merci d'avance de votre aide si vous avez une idée !

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Tu utilises les tables temporaires comme dans SqlServer mais c'est différent sur Oracle, cf asktom sur les tables temporaires.
    the main exception being that they are 'statically' defined. You create
    them once per database, not once per stored procedure in the database.
    Il existe sûrement d'autres entrées autour de ce sujet sur asktom.
    Sinon concernan l'insert, le curseur semble inutile, il vaut mieux juste un insert :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    insert into MA_TABLE
    select * from TMP_MA_TABLE
    Une autre entrée où l'utilisation est plutôt comme une interface :
    http://asktom.oracle.com/pls/apex/f?...15826034070548

  3. #3
    Expert éminent
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 821
    Points : 6 443
    Points
    6 443
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    Pour créer une procédure qui utilise une table qui n'existe pas encore, il faut faire du SQL dynamique.
    Mais pour une table temporaire, sous Oracle, il ne faut pas la créer à chaque fois, mais créer une Global Temporary Table.
    Cordialement,
    Franck.
    Franck Pachot - Developer Advocate Yugabyte 🚀 Base de Données distribuée, open source, compatible PostgreSQL
    🗣 twitter: @FranckPachot - 📝 blog: blog.pachot.net - 🎧 podcast en français : https://anchor.fm/franckpachot

  4. #4
    Candidat au Club
    Inscrit en
    Décembre 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Tu utilises les tables temporaires comme dans SqlServer mais c'est différent sur Oracle, cf asktom sur les tables temporaires.

    Il existe sûrement d'autres entrées autour de ce sujet sur asktom.
    Sinon concernan l'insert, le curseur semble inutile, il vaut mieux juste un insert :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    insert into MA_TABLE
    select * from TMP_MA_TABLE
    Une autre entrée où l'utilisation est plutôt comme une interface :
    http://asktom.oracle.com/pls/apex/f?...15826034070548
    En fait je me suis mal exprimé : j'utilise une table temporaire mais pas au sens TEMPORARY TABLE. C'est une table classique en fait.

    Sinon mon curseur me sert à parcourir les lignes une à une. J'en ai besoin car en cas de rejet d'insertion sur une ligne je récupère certaine infos (ROWID...).

  5. #5
    Candidat au Club
    Inscrit en
    Décembre 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par pachot Voir le message
    Bonjour,
    Pour créer une procédure qui utilise une table qui n'existe pas encore, il faut faire du SQL dynamique.
    Oui je parviens bien à générer la requête d'insertion mais le problème c'est faire une LOOP pour parcourir chaque enregistrement. Pour l'instant j'ai le code suivant mais je vois pas comment faire une boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    BEGIN
       DWH.CREATE_TMP ('TMP_TOTO', 'SELECT * FROM ...');
     
       REQ := 'INSERT INTO TOTO (ch1, ch2) (SELECT ch1, ch2 FROM TMP_TOTO)';
       EXECUTE IMMEDIATE REQ;
    END;

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Il y a pas mal de chose dans la doc notemment si tu veux BULK LOADER : Native Dynamic SQL
    voici un exemple :
    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
    SQL> create table MA_TABLE (a number, b varchar2(10))
      2  /
     
    Table created.
     
    SQL> declare
      2    l_select varchar2 (100);
      3    l_insert varchar2 (100);
      4    l_cursor sys_refcursor;
      5    l_rec  MA_TABLE%rowtype;
      6  begin
      7    execute immediate 'create table TMP_MA_TABLE (a number, b varchar2(10))';
      8    execute immediate 'insert into TMP_MA_TABLE (a, b) values (1,''toto'')';
      9    commit;
     10    l_select := 'select a,b from TMP_MA_TABLE';
     11    open l_cursor for l_select;
     12      loop fetch l_cursor into l_rec;
     13        exit when l_cursor%notfound;
     14  
     15        l_insert := 'insert into MA_TABLE (a, b) values (:1, :2)';
     16        execute immediate l_insert using l_rec.a, l_rec.b;
     17      end loop;
     18    close l_cursor;
     19    commit;
     20    execute immediate 'drop table TMP_MA_TABLE';
     21  end;
     22  /
     
    PL/SQL procedure successfully completed.
     
    SQL> select * from ma_table
      2  /
     
             A B
    ---------- ----------
             1 toto
     
    SQL> drop table ma_table
      2  /
     
    Table dropped.
    Par contre je ne vois tout de même pas l'intérêt de supprimer et recréer la table, autant la conserver.

  7. #7
    Candidat au Club
    Inscrit en
    Décembre 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Il y a pas mal de chose dans la doc notemment si tu veux BULK LOADER : Native Dynamic SQL
    voici un exemple :

    Par contre je ne vois tout de même pas l'intérêt de supprimer et recréer la table, autant la conserver.
    Merci ça marche effectivement très bien comme ça !

    Quant à la suppression moi non plus je ne vois pas l'intérêt mais je me plie aux normes de devs

  8. #8
    Candidat au Club
    Inscrit en
    Décembre 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Il y a pas mal de chose dans la doc notemment si tu veux BULK LOADER : Native Dynamic SQL
    voici un exemple :
    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
    SQL> create table MA_TABLE (a number, b varchar2(10))
      2  /
     
    Table created.
     
    SQL> declare
      2    l_select varchar2 (100);
      3    l_insert varchar2 (100);
      4    l_cursor sys_refcursor;
      5    l_rec  MA_TABLE%rowtype;
      6  begin
      7    execute immediate 'create table TMP_MA_TABLE (a number, b varchar2(10))';
      8    execute immediate 'insert into TMP_MA_TABLE (a, b) values (1,''toto'')';
      9    commit;
     10    l_select := 'select a,b from TMP_MA_TABLE';
     11    open l_cursor for l_select;
     12      loop fetch l_cursor into l_rec;
     13        exit when l_cursor%notfound;
     14  
     15        l_insert := 'insert into MA_TABLE (a, b) values (:1, :2)';
     16        execute immediate l_insert using l_rec.a, l_rec.b;
     17      end loop;
     18    close l_cursor;
     19    commit;
     20    execute immediate 'drop table TMP_MA_TABLE';
     21  end;
     22  /
     
    PL/SQL procedure successfully completed.
     
    SQL> select * from ma_table
      2  /
     
             A B
    ---------- ----------
             1 toto
     
    SQL> drop table ma_table
      2  /
     
    Table dropped.
    Je relance le sujet pour une question additionnelle : je dois, en cas de rejet lors de l'insertion de la ligne dans MA_TABLE, lancer une procédure spécifique avec le ROWID de la ligne en question.
    Le problème c'est que je parcours le curseur de type MA_TABLE%rowtype. Donc quand je lance la procédure avec en paramètre l_rec.ROWID il ne le connait pas évidemment.
    Merci de votre aide.

  9. #9
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Utilisez un curseur modèle pour déclarer le rowid
    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
     
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 
    Connected as mni
     
    SQL> 
    SQL> declare
      2    cursor crs_modele Is
      3      Select rowid, t.*
      4        From ma_table t;
      5    --
      6    SubType rMa_Table Is crs_modele%RowType;
      7    l_var   rMa_Table;
      8  Begin
      9    Null;
     10  End;
     11  /
     
    PL/SQL procedure successfully completed
     
    SQL>

  10. #10
    Candidat au Club
    Inscrit en
    Décembre 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Utilisez un curseur modèle pour déclarer le rowid

    Merci beaucoup !

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

Discussions similaires

  1. Affichage d'une colonne sur une table pas complète
    Par leloup84 dans le forum Langage SQL
    Réponses: 12
    Dernier message: 19/08/2011, 09h33
  2. Requête qui ne marche pas sur une table Joomla.
    Par tintin72 dans le forum Requêtes
    Réponses: 2
    Dernier message: 26/02/2010, 17h51
  3. Clef primaire sur une table qui n'en a pas d'après PhpMyAdmin
    Par bubulemaster dans le forum Requêtes
    Réponses: 5
    Dernier message: 11/04/2009, 18h44
  4. Réponses: 2
    Dernier message: 03/03/2007, 19h03
  5. curseur sur une table dont on ne connaît pas le nom
    Par NPortmann dans le forum Oracle
    Réponses: 4
    Dernier message: 12/07/2005, 09h04

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