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 :

Enregistrement issu d'un curseur dynamique


Sujet :

SQL Oracle

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut [Résolu] Enregistrement issu d'un curseur dynamique
    Bonjour !

    Sous PL/SQL, je tente de déclarer un enregistrement de type tuple de curseur dynamique, sans succès.
    Mon but est d'éditer l'ensemble des tuples d'une table passée en paramètre dans une procédure stockée.

    Voilà le code :
    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
     
    CREATE OR REPLACE PROCEDURE edition_table (nom_table VARCHAR) AS
     
    	TYPE DynCurs IS REF CURSOR;
    	tuples DynCurs;
    	un_tuple tuples%ROWTYPE;
     
    BEGIN
    	DBMS_OUTPUT.PUT_LINE('Edition de la table '||nom_table||' :');
    	OPEN tuples FOR
    	   'SELECT * FROM '||nom_table||'';
    	FETCH tuples INTO un_tuple ;
    	WHILE tuples%FOUND LOOP
    		--traitement
    		FETCH tuples INTO un_tuple ;
    	END LOOP;
    	CLOSE tuples;
    END;
    /
    La seule solution que j'envisage pour déclarer "un_tuple" c'est le passage par un record d'où l'utilisation de %ROWTYPE...

    Est-ce que cela est possible ?

    Que faut-il corriger ?

    Merci d'avance !

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Alors le ROWTYPE ne marchera pas car il faut que Oracle soit en mesure de déterminer la composition de ta requete.

    Donc le seul moyen est de définir un record.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    le seul moyen est de définir un record
    Etant donné que la table est passée en paramètre de la procédure, je ne peux pas définir mon record par avance !!!

    Y'a-til une autre solution ?

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    oui et non tout depend de ce que tu veux en sortie.

    Si tu veux une seule colonne de résultat (genre toute les colonnes concaténée), ou plusieurs colonnes.


    Tout depend de ce que tu veux au final

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    Merci de tes réponses.
    Ce que je veux au final, c'est exactement ce qu'on obtiendrait avec un select * from NOM_TABLE
    !

    J'ai essayé de passer par une chaîne de caractère (chaine).
    Et de parcourir le curseur en passant par cette chaine (
    FETCH tuples INTO chaine ;
    )...
    Le problème est que je ne récupère ainsi que le premier champ.
    En multipliant ces variables chaines, j'arrive à accéder à tous les champs.
    Le problème est que les tables passées en paramètre n'ont pas forcément le même nombre de champs...

    Une autre solution possible : un tableau de chaines de caractères (?) ...

    Toujours un problème qui se pose : comment parcourir le curseur avec mon tableau ?
    FETCH tuples INTO mon_tableau(1), mon_tableau(2).....mon_tableau(N);

    Je suis désemparée !!!

  6. #6
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Tu veux juste de l'affichage ou pas . Car si c'est juste avoir le resultat affiché il te suffit de faire la construction de la requete de maniere dynamique de maniere a concatener toute tes colonnes les unes aux autre.

    A la rigueur avec cette maniere tu as la possibilité de recuperer toute tes colonnes dans une variable et ensuite de la parser pour retrouver les valeurs de chaques colonnes.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    Ben, oui, c'est uniquement de l'affichage que je veux...

    Par contre, je comprends pas trop ta solution !!!
    Désolée...

  8. #8
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Ahhhh si c 'est juste de l'affichage bon alors attend je vais te faire un truc

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    Voilà ma soluce avec un tableau de chaine de caractères :
    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
    CREATE OR REPLACE PROCEDURE edition_table (nom_table VARCHAR) AS
     
    	TYPE DynCurs IS REF CURSOR;
    	tuples DynCurs;
    	TYPE TableChar IS TABLE OF VARCHAR(20);
    	mes_tuples TableChar := TableChar();
    	nb_tuples INTEGER:=0;
     
     
    	--un_tuple tuples%ROWTYPE;
     
    BEGIN
    	EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||nom_table||'' INTO nb_tuples;	
    	--DBMS_OUTPUT.PUT_LINE(TO_CHAR(nb_tuples));
    	DBMS_OUTPUT.PUT_LINE('Edition de la table '||nom_table||' :');
    	OPEN tuples FOR 
    	   'SELECT * FROM '||nom_table||'';
    	FETCH tuples INTO ???????? ;
    	WHILE tuples%FOUND LOOP
    		--traitement d'affichage
    		--FETCH tuples INTO un_tuple ;
    --	END LOOP;
    	CLOSE tuples;
    END;
    /

    Comment paramétrer les ??????

  10. #10
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Voila un exemple

    Attention cependant ce code ne gere pas tout, j'ai fait ca en deux minutes et y a beaucoup de cas particulier pas pris en compte.

    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
    CREATE OR REPLACE PROCEDURE edition_table(nom_table VARCHAR) AS
      TYPE dyncurs IS REF CURSOR;
      curdyn dyncurs;
      CURSOR cur_col IS
        SELECT cname, coltype FROM col WHERE tname = nom_table;
      col_list   CLOB;
      v_resultat VARCHAR2(32676);
      v_requete  VARCHAR2(32676);
    BEGIN
      -- ON recherche les colonnes de la table.
      FOR rec IN cur_col LOOP
        -- Si c'est de la date
        IF rec.coltype = 'DATE' THEN
          col_list := col_list || ' || '' '' || TO_CHAR(' || rec.cname ||
                      ',''DD/MM/RRRR HH24:MI:SS'')';
        ELSIF rec.coltype LIKE '%CHAR%' THEN
          col_list := col_list || ' || '' '' || ' || rec.cname;
        ELSIF rec.coltype = 'NUMBER' THEN
          col_list := col_list || ' || '' '' || ' || rec.cname;
        END IF;
      END LOOP;
      -- on efface les deux premiers || ' ' ||
      col_list  := substr(col_list, 11);
      v_requete := 'SELECT ' || col_list || ' AS RESULTAT FROM ' || nom_table;
      OPEN curdyn FOR v_requete;
      LOOP
        FETCH curdyn
          INTO v_resultat;
        EXIT WHEN curdyn%NOTFOUND;
        dbms_output.put_line(v_resultat);
      END LOOP;
    END;

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    Ai pas encore eu le temps de ma plonger dans ta soluce...
    Voilà ce que j'ai tenté de faire avec mon tableau :
    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
    CREATE OR REPLACE PROCEDURE edition_table (nom_table VARCHAR) AS
     
    	TYPE DynCurs IS REF CURSOR;
    	tuples DynCurs;
    	TYPE TableChar IS TABLE OF VARCHAR(20);
    	mes_tuples TableChar := TableChar();
    	nb_tuples INTEGER:=0;
    	chaine_champs VARCHAR(100);
    	compteur INTEGER;
     
     
    BEGIN
    	EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||nom_table||'' INTO nb_tuples;	
    	--DBMS_OUTPUT.PUT_LINE(TO_CHAR(nb_tuples));
     
    	FOR compteur IN 1..nb_tuples LOOP
    	   chaine_champs:=chaine_champs||'mes_tuples('||compteur||'),';
    	END LOOP;
    	chaine_champs:=SUBSTR(chaine_champs,1,(LENGTH(chaine_champs)-1));
    	DBMS_OUTPUT.PUT_LINE(chaine_champs);
    	mes_tuples.extend(nb_tuples);	
     
    	DBMS_OUTPUT.PUT_LINE('Edition de la table '||nom_table||' :');
     
    	OPEN tuples FOR 
    	   'SELECT * FROM '||nom_table||'';
    	FETCH tuples INTO chaine_champs ;
    	WHILE tuples%FOUND LOOP
    		DBMS_OUTPUT.PUT_LINE(mes_tuples(1));
    		FETCH tuples INTO chaine_champs ;
    	END LOOP;
     
    	CLOSE tuples;
     
     
    END;
    /
    Le problème est que chaine_champs ne se traduit pas par son contenu en caractères....
    Du coup, chaine_champs contient la première colonne de la table passée en paramètre....

    C'est assez chaud comme truc !!!

    Comment faire en sorte que le contenu de chaine_champs s'inscrive texto :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    FETCH tuples INTO mes_tuples(1),mes_tuples(2),mes_tuples(3);
    ??????

  12. #12
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Regarde ma solution je vais voir si il est possible de définir un record dynamique.

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    A la création de ta procédure, j'ai des erreurs :
    LINE/COL ERROR
    -------- --------------------------------------------------------------
    14/7 PL/SQL: Statement ignored
    14/19 PLS-00306: wrong number or types of arguments in call to '||'
    16/7 PL/SQL: Statement ignored
    16/19 PLS-00306: wrong number or types of arguments in call to '||'
    18/7 PL/SQL: Statement ignored
    18/19 PLS-00306: wrong number or types of arguments in call to '||'
    22/3 PL/SQL: Statement ignored
    22/16 PLS-00306: wrong number or types of arguments in call to 'SUBS
    23/3 PL/SQL: Statement ignored
    23/16 PLS-00306: wrong number or types of arguments in call to '||'
    Je vois pas ce que c'est !

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    Je ne connais pas le type CLOB...
    Tu peux m'éclairer, stp ?

  15. #15
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Le type CLOB c'est une chaine de caractère de longeur variable pouvant aller jusqu'a 2Go. C'est pour eviter d'avoir des pb avec la requete (mais bon c vrai que j'aurais pu utiliser VARCHAR2(32676))

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    ok, c bon !

  17. #17
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    En modifiant CLOB en VARCHAR, j'ai plus d'erreur à la création de la procédure...
    En revanche, elle plante à l'exécution :
    ERREUR à la ligne 1 :
    ORA-00936: missing expression
    ORA-06512: at "ISEA25.EDITION_TABLE2", line 24
    ORA-06512: at line 1
    C'est balot !!!

  18. #18
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Bon moi avec ce code ca marche

    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
    CREATE OR REPLACE PROCEDURE edition_table(nom_table VARCHAR) AS
      TYPE dyncurs IS REF CURSOR;
      curdyn dyncurs;
      CURSOR cur_col IS
        SELECT cname, coltype FROM col WHERE tname = nom_table;
      col_list   VARCHAR2(32676);
      v_resultat VARCHAR2(32676);
      v_requete  VARCHAR2(32676);
    BEGIN
      -- ON recherche les colonnes de la table.
      FOR rec IN cur_col LOOP
        -- Si c'est de la date
        IF rec.coltype = 'DATE' THEN
          col_list := col_list || ' || '' '' || TO_CHAR(' || rec.cname ||
                      ',''DD/MM/RRRR HH24:MI:SS'')';
        ELSIF rec.coltype LIKE '%CHAR%' THEN
          col_list := col_list || ' || '' '' || ' || rec.cname;
        ELSIF rec.coltype = 'NUMBER' THEN
          col_list := col_list || ' || '' '' || ' || rec.cname;
        END IF;
      END LOOP;
      -- on efface les deux premiers || ' ' ||
      col_list  := substr(col_list, 11);
      v_requete := 'SELECT ' || col_list || ' AS RESULTAT FROM ' || nom_table;
      OPEN curdyn FOR v_requete;
      LOOP
        FETCH curdyn
          INTO v_resultat;
        EXIT WHEN curdyn%NOTFOUND;
        dbms_output.put_line(v_resultat);
      END LOOP;
    END;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    begin
      -- Call the procedure
      edition_table(nom_table => 'EMP');
    end;

  19. #19
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 20
    Points : 7
    Points
    7
    Par défaut
    C'est dommage parce que moi, j'ai toujours la même erreur...
    Je suis verte !

    Je pense qu'on travaille pas sur les mêmes outils...
    SQL+ d'Oracle pour moi

    A l'appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    execute edition_table('toto');
    Et toujours la même erreur !

    Je sens mal le "AS RESULTAT FORM".
    J'ai ôté le "AS RESULTAT"... Sans succès !

  20. #20
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2003
    Messages : 412
    Points : 1 326
    Points
    1 326
    Par défaut
    Bon moi je bosse avec un autre outils.

    Je suis sur Oracle 9i

    Donc le pb ne viens pas du AS

    Par contre il peux venir du fait que tu tentes d'excuter ma procédure sur une table ou il a autres choses que des colonnes VARCHAR2, DATE, et NUMBER

    Tente ce code qui lui va t'afficher la requete générée

    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
    CREATE OR REPLACE PROCEDURE edition_table(nom_table VARCHAR) AS
      TYPE dyncurs IS REF CURSOR;
      curdyn dyncurs;
      CURSOR cur_col IS
        SELECT cname, coltype FROM col WHERE tname = nom_table;
      col_list   VARCHAR2(32676);
      v_resultat VARCHAR2(32676);
      v_requete  VARCHAR2(32676);
    BEGIN
      -- ON recherche les colonnes de la table.
      FOR rec IN cur_col LOOP
        -- Si c'est de la date
        IF rec.coltype = 'DATE' THEN
          col_list := col_list || ' || '' '' || TO_CHAR(' || rec.cname ||
                      ',''DD/MM/RRRR HH24:MI:SS'')';
        ELSIF rec.coltype LIKE '%CHAR%' THEN
          col_list := col_list || ' || '' '' || ' || rec.cname;
        ELSIF rec.coltype = 'NUMBER' THEN
          col_list := col_list || ' || '' '' || ' || rec.cname;
        END IF;
      END LOOP;
      -- on efface les deux premiers || ' ' ||
      col_list  := substr(col_list, 11);
      v_requete := 'SELECT ' || col_list || ' AS RESULTAT FROM ' || nom_table;
      dbms_output.put_line(v_requete);
      /*  OPEN curdyn FOR v_requete;
      LOOP
        FETCH curdyn
          INTO v_resultat;
        EXIT WHEN curdyn%NOTFOUND;
        dbms_output.put_line(v_resultat);
      END LOOP;*/
    END;
    ensuite tente d'executer la requete (c'est de la que viens le probleme)

    Pour info il n'est pas possible d'avoir une sorte de record dynamique

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

Discussions similaires

  1. [PL/SQL] Curseur dynamique
    Par dcollart dans le forum Oracle
    Réponses: 2
    Dernier message: 09/11/2009, 10h08
  2. [Debutant] Appel d'enregistrement issu d'une autre table
    Par grasduslip dans le forum Access
    Réponses: 15
    Dernier message: 21/07/2006, 16h34
  3. Curseur dynamique
    Par dcollart dans le forum Oracle
    Réponses: 1
    Dernier message: 09/05/2006, 11h06
  4. Réponses: 3
    Dernier message: 11/10/2005, 19h13
  5. ODBC et curseurs dynamique!!!
    Par F@keur dans le forum MFC
    Réponses: 7
    Dernier message: 30/03/2005, 20h05

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