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 :

[PL/SQL] Charger une table dans une collection


Sujet :

Oracle

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2003
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 13
    Points : 11
    Points
    11
    Par défaut [PL/SQL] Charger une table dans une collection
    Bonjour,

    je souhaiterais charger le contenu d'une table dans une collection (ou un autre type de structure si c'est plus approprié) pour pouvoir la réinjecter (avec quelques traitement au passage) dans une autre table.

    J'ai suivi ce que la doc de SheikYerbouti dit à ce sujet, à savoir j'ai executer 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
     
    DECLARE
     
        TYPE TYP_TAB_AGENT IS TABLE OF RHAP_PERSONAL_DATA%Rowtype ;
        Tabagent TYP_TAB_AGENT ;
     
    BEGIN
    select * BULK COLLECT into Tabagent from RHAP_PERSONAL_DATA;
     
    For i IN Tabagent.first..Tabagent.last Loop
     dbms_output.put_line( Tabagent(i).matricule ) ;
    End loop ;
     
    END;
    /
    J'ai l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select * BULK COLLECT into Tabagent from RHAP_PERSONAL_DATA;
                               *
    ERREUR à la ligne 2 :
    ORA-06550: Ligne 2, colonne 28 :
    PLS-00201: l'identificateur 'TABAGENT' doit être déclaré
    La doc précise que les bout de codes sont garanties pour oracle 9i, et je suis en présence d'oracle 8i.

    Pour le moment j'ai le code suivant qui 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
     
    TYPE TAB_AGENT_PRENOM IS TABLE OF RHAP_PERSONAL_DATA.NAME%type;
    TYPE TAB_AGENT_MAT IS TABLE OF RHAP_PERSONAL_DATA.EMPLID%type;
    TYPE TAB_AGENT_CIV IS TABLE OF RHAP_PERSONAL_DATA.NAME_PREFIX%type;
    TYPE TAB_AGENT_NOM IS TABLE OF RHAP_PERSONAL_DATA.FIRST_NAME%type;
     
    prenom		  TAB_AGENT_PRENOM;
    nom			  TAB_AGENT_NOM;
    matricule	  TAB_AGENT_MAT;
    civilite	  TAB_AGENT_CIV;
     
    BEGIN
    select EMPLID, NAME, FIRST_NAME, NAME_PREFIX BULK COLLECT into matricule, nom, prenom,
    civilite from RHAP_PERSONAL_DATA;
    Cependant j'aimerai utiliser une seule et même structure de données.

    Merci de votre aide

  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
    Le problème en 8i vient peut-être seulement du BULK COLLECT

    essayez avec un FETCH standard

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    declare
      type TYPE_T is table of TEST%ROWTYPE INDEX BY BINARY_INTEGER;
      t type_t ;
      cursor CC is select * from TEST ;
      n pls_integer := 1 ;
    Begin
      Open  CC ;
      fetch CC into t(n) ;
      While CC%FOUND Loop
    	n := n + 1 ;
        fetch CC into t(n) ;	
      End loop ;
    End ;
    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 à l'essai
    Profil pro
    Inscrit en
    Août 2003
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 13
    Points : 11
    Points
    11
    Par défaut
    Avec un fetch ca marche.

    Cependant j'ai d'autres questions et remarques :

    - Est ce qu'avec un fetch standard (sans BULK COLLECT), ce n'est pas plus (trop) lent ? (théoriquement ca l'est, mais qu'en est il de la pratique ?)

    - Y a t il une limite de taille pour les collections ? Je dois faire faire des translation de contenu entre tables (extraction de contenu d'une table, traitement et reinjection dans une autre table), et je pense que tout charger dans une collection, traiter et reinjecter doit être une mauvaise idée, n'est ce pas ? Il est peut être préférable de charger/traiter/injecter par bloc de donnée et faire des commits réguliers (genre tous les 1000 lignes). Qu'en pensez vous ?

    Une remarque concernant le BULK COLLECT : voici un extrait du site http://www.unix.org.ua/orelly/oracle/guide8i/ch05_03.htm
    Here are some rules and restrictions to keep in mind when using BULK COLLECT:

    *The collections you reference can only store scalar values (string, number, date). In other words, you cannot fetch a row of data into a record structure that is a row in a collection.
    Donc effectivement charger directement avec BULK COLLECT une ligne de table dans une ligne de collection n'est pas possible.

  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
    Si vous devez manipuler des volumes d'informations importants, je vous conseille de déporter votre traitement dans une procédure stockée.
    Vous bénéficierez du BULK COLLECT et éviterez le transit de gros volumes entre la base et votre application.
    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 à l'essai
    Profil pro
    Inscrit en
    Août 2003
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 13
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par SheikYerbouti
    Si vous devez manipuler des volumes d'informations importants,
    Oui c'est la cas

    Citation Envoyé par SheikYerbouti
    je vous conseille de déporter votre traitement dans une procédure stockée. Vous bénéficierez du BULK COLLECT et éviterez le transit de gros volumes entre la base et votre application.
    C'est ce que je fais déjà, mais je vois pas en quoi le fait d'être dans une procédure stockée me permet de mieux gérer les gros volumes de données. Lors de chargement de données dans une collection, les données sont bien chargé en mémoire ? donc il y a une limitation en terme de quantité de données pour les collections ? Dés lors comment gérer le transit de gros volume de données ?

  6. #6
    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
    Hum, j'ai cru que vous récupériez vos données dans une application tierce.
    Si tout est fait au niveau du noyau, pas de problème.
    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

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2003
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 13
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par SheikYerbouti
    Si tout est fait au niveau du noyau, pas de problème.
    Cela dit, n'y a t il pas des soucis ou des préconisations lors du chargement des données dans les collections avec le bulk collect ? A savoir par exemple, ne pas charger toutes la table (gros volume) dans les collections mais le faire par pallier ? Les collections doivent bien avoir une taille limite ?

    Merci

  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
    Non, il n'y a pas de limite de taille à une collection.

    Mais il faut se tenir aux limites du bon sens.
    Il est aussi "lourd" de gérer des collections de centaines de milliers voir millions d'enregistrements que faire un UPDATE de millions de lignes sur une table.

    N'oubliez pas que le BULK COLLECT possède une option LIMIT permettant une gestion par paquets.
    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 à l'essai
    Inscrit en
    Février 2005
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 10
    Points : 10
    Points
    10
    Par défaut
    bonjour,
    j'utilise Bulk collect limit et Forall et ca marche tres fort !!!
    Le bulk combiné au LIMIT et au FORALL te permet de faire de l'update de masse sans exploser le rollback et de facon tres rapide.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2003
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 13
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par boyardeC
    Le bulk combiné au LIMIT et au FORALL te permet de faire de l'update de masse sans exploser le rollback et de facon tres rapide.
    Bonjour,

    est il possible d'avoir un bout de ton code où tu utilises bulk + limit + FORALL pour comparer avec mon code, histoire de voir si je code proprement.

    merci bcp

    PS: Merci SheikYerbouti

  11. #11
    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 jeter un coup d'oeil sur l'article PL/SQL disponible sur la page Cours Oracle ?
    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.

Discussions similaires

  1. copier une table d'une BDD dans une table d'une autre BDD
    Par faniette dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/05/2013, 10h17
  2. Réponses: 7
    Dernier message: 25/03/2011, 10h52
  3. [AC-2003] insert des données d'une table dans une table d'une base externe
    Par marieo dans le forum VBA Access
    Réponses: 1
    Dernier message: 30/11/2009, 14h29
  4. [SQL]insérer le total d'une requete dans une table
    Par toadnam dans le forum Requêtes et SQL.
    Réponses: 9
    Dernier message: 31/05/2007, 11h17
  5. [SQL] automatiser l'effacement d'une ligne dans une table
    Par nebil dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 15/04/2006, 10h31

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