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

SQL Loader : problème champ ID


Sujet :

SQL*Loader Oracle

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut SQL Loader : problème champ ID
    Bonjour à tous,

    J'ai un fichier plat que je dois charger dans Oracle 9i par un SQL Loader, dans une table qui contient un champ ID servant de clé primaire. Or dans mon fichier texte je n'ai pas de donnée pour ce champ.

    Pour plus de précisions, voici la structure de mon fichier :


    Champ1 X(8)
    Champ2 X(10)
    Champ3 N(10,2)

    Et la structure de ma table

    ID NUMBER,
    CH1 VARCHAR2(8),
    CH2 VARCHAR2(10),
    CH3 NUMBER(10,2)

    Ma question est donc : comment puis-je faire pour alimenter la colonne ID avec des valeurs s'incrémentant à chaque enregistrement ?

    Merci d'avance de votre aide.

  2. #2
    Nouveau membre du Club
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    61
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 61
    Points : 36
    Points
    36
    Par défaut
    salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create sequence ta_table_id;
    create trigger ta_table_seq_t before insert on ta_table
    for each row
    when (new.id is null)
    begin
     select ta_table_id.nextval into :new.id from dual
    end;
    update ta_table set id=ta_table_id.nextval;
    Si j'ai bien compris ce que tu veux ça doit être quelque chose de ce genre

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Bonjour,

    Effectivement j'avais pensé à quelque chose dans ce genre là, mais voilà, problème de taille (que j'ai oublié de signaler d'ailleurs, honte à moi ), la base Oracle est celle d'un progiciel sur laquelle je n'ai pas le droit de créer des séquences ni des triggers, de même que je n'ai pas le droit de modifier le modèle de données autrement que via l'outil (d'où ces ... de champ ID qui me sont imposés...)

    J'avais pensé à charger mes données via SQL Loader dans une table de travail, et de la faire un insert dans ma table définitive en remplissant mes ID par un SELECT ROWNUM, mais je voudrais quelque chose de plus "propre" qui m'éviterait de passer par une table intermédiaire...

    Merci en tous cas pour la réponse, en espérant qu'il y en aura d'autres.

  4. #4
    Membre régulier
    Inscrit en
    Mars 2004
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 98
    Points : 74
    Points
    74
    Par défaut
    Si tu as une sequence qui alimente le champ PK, tu peux rajouter cela dans ton fichier controle :
    ID "taSequence.NEXTVAL"

    sans que le champ Id existe dans le fichier à charger.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Malheureusement non, je n'ai pas de séquence, tout le problème est là.... Et il faut que je la "simule" manuellement, puisque je n'ai pas le droit d'en créer...

    Mais merci à toi d'avoir essayé de m'aider ! Si tu as d'autres idées, je suis preneur !

  6. #6
    Membre habitué
    Inscrit en
    Août 2006
    Messages
    181
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 181
    Points : 166
    Points
    166
    Par défaut
    bonjour,
    j'ai fait cet exemple qui pourra t'aider probablement :

    create table test (id number(3),ch varchar2(10));
    insert into test values (0,'');
    insert into test (id,ch) values ((select max(id)+1 from test),'bb');
    ...
    delete test where id=0 -- pour supprimer le premier élément sur lequel on c'est basé pour commencer l'incrementation

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci de ton aide Oraman, mais cela ne répond pas à mon problème car :

    - je pars d'un fichier pour le charger par SQL Loader
    - je ne peux donc pas utiliser de SQL

    Et si je dois en venir à une solution où je dois faire des inserts (donc en passant par une table intermédiaire sans ID), autant utiliser ROWNUM, ça me paraît plus "propre" que MAX + 1.

  8. #8
    Membre du Club
    Inscrit en
    Février 2006
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 33
    Points : 40
    Points
    40
    Par défaut
    bonjour,
    si tu as le droit de créer des fonction dans cette base de données cela résoudra ton problème, sinon il te restera mon avis, de créer un petit programme(script shell avec awk si tu utilise Unix) pour ajouter n caractères qui feront l'affaire d'une clé.
    salutations.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    A priori je répondrais que oui, j'ai le droit de créer des fonctions, puisque je crée des procédures stockées.

    Mais je ne vois pas bien où tu veux en venir avec une fonction ?

    Pour ce qui est su script Shell qui rajoute des caractères, effectivement ça peut être une idée...

  10. #10
    Membre du Club
    Inscrit en
    Février 2006
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 33
    Points : 40
    Points
    40
    Par défaut
    si tu as le droit de créer des fonctions il alors très simple de résoudre ce problème:
    1. Tu vas créer un fonction qui va te retourner ton ID se basant sur le nombre d'enregistrements dans ta table en y ajoutant 1,ou bien obtenir le max des ID de la table et l'incrémenter aussi( code 1).
    2. tu donnes le droit d'exécution de ta fonction à l'utilisateur avec lequel tu exécute chargement SQL*LOADER( code 2).
    3. en fin tu fais appel à cet fonction au niveau de ton fichier de control SQL*LOADER( code 3).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE OR REPLACE FUNCTION NEXT_ID RETURN PLS_INTEGER
    AS
       V_RET_VALUE PLS_INTEGER default 0;
    BEGIN
       SELECT NVL(max(ID),0)+1  
        INTO V_RET_VALUE
       FROM ma_table;
     
      RETURN V_RET_VALUE;
    EXCEPTION
      --gères tes exceptions
    END NEXT_ID;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GRANT EXECUTE ON  NEXT_ID TO TON_USER
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    extrait du ctl
    ...
    INTO ma_table
    (
    ID  "NEXT_ID()",
    CH1   POSITION(X:Y),
    CH2   POSITION(A:B)
    )
    je ne sais pas les parenthèses sont nécessaires ou pas essai les deux cas.
    bon courage.

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci pour l'idée Hadlak, j'ai essayé de mettre en place cela.

    J'ai créé la fonction, et modifié mon control file comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    LOAD DATA 
    INFILE '../in/MonFichier.csv'
    TRUNCATE
    INTO TABLE MA_TABLE
    FIELDS TERMINATED BY ';'
    (  ID "NEXT_ID()",
       STE_C,
       ENT_C, 
       ENT_DOM,
       GSC_TC
        )
    Et j'obtiens l'erreur suivante dans le log de mon SQL Loader :
    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
       Column Name                  Position   Len  Term Encl Datatype
    ------------------------------ ---------- ----- ---- ---- ---------------------
    ID                                  FIRST     *   ;       CHARACTER
        SQL string for column : "NEXT_ID()"
    STE_C                             NEXT     *   ;       CHARACTER
    ENT_C                             NEXT     *   ;       CHARACTER
    ENT_DOM                           NEXT     *   ;       CHARACTER
    GSC_TC                            NEXT     *   ;       CHARACTER
     
    Record 1: Rejected - Error on table MA_TABLE
    ORA-00604: error occurred at recursive SQL level 1
    ORA-01502: index '.' or partition of such index is in unusable state
     
    Record 2: Rejected - Error on table MA_TABLE.
    ORA-00604: error occurred at recursive SQL level 1
    ORA-01502: index '.' or partition of such index is in unusable state
    et ceci pour tous mes enregistrements...


    Je précise que j'utilise ce Loader depuis un script Shell qui :
    1. execute un SQL PLUS pour créer ma table
    2. Lancer le SQLLDR pour la charger
    3. execute un autre SQL PLUS pour faire des updates

    Merci de votre aide.

  12. #12
    Membre du Club
    Inscrit en
    Février 2006
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 33
    Points : 40
    Points
    40
    Par défaut
    bonjour,
    l'erreur ORA-01502 indique un accès à un index ou une partition(si la table est partitionné) qui marqué comme invalide.
    généralement le problème apparait avec sql loader et des opération DDL qui nécessitent beaucoup d'espace dans le tablespace temporaire.
    il est possible que tes enregistrement soit déjà charger mais oracle n'a pas pu seulement créer les index donc merci de :
    • verifier si tes enregistrement sont charger.
    • vérifier si il ya de l'espace sur le tablespace temporaire.
    • vérifier si il ya pas d'indexes invalides :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      SELECT * from USER_INDEXES WHERE STATUS = ‘INVALID’;

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Bonjour hadlak,

    Pour répondre à tes questions :

    - mes enregistrements ne sont pas chargés
    - je n'utilise aucun index sur ma table (même pas une clé ni une contrainte)
    - la requête de recherche des index invalides ne renvoie aucun enregistrement.

    Peut-être devrais-je faire un COMMIT dans le script SQLPLUS qui crée ma table (et qui est exécuté juste avant de charge les données par SQLLDR) ?

    En tous cas merci de ton aide.

  14. #14
    Membre du Club
    Inscrit en
    Février 2006
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 33
    Points : 40
    Points
    40
    Par défaut
    le commit n'est pas nécessaire pour un create.
    et l'espace dans le tablespace temporaire ?

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Je n'y ai pas directement accès, je n'ai pas les privilèges suffisants pour voir les tablespaces.

    Je contacte mon DBA tout de suite (enfin, si j'arrive à le joindre) ...

    I'll be back soon !

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Effectivement, mes Tablespaces d'index et Temp sont pleins...

    CQFD.

    Merci à tous ceux qui m'ont répondu, et en particulier à Hadlak.

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

Discussions similaires

  1. Sql Loader - Problème avec 0d0a dans un champ texte
    Par frglyon dans le forum Import/Export
    Réponses: 0
    Dernier message: 18/02/2014, 08h27
  2. [SQL LOADER] problème d'ordonnancement de champs
    Par Ginseng dans le forum Import/Export
    Réponses: 2
    Dernier message: 12/06/2009, 13h34
  3. 8i : sql loader et champ texte sur plusieurs lignes
    Par naonedboy dans le forum SQL*Loader
    Réponses: 1
    Dernier message: 23/11/2005, 10h07
  4. [SQL*Loader] Problème de chargement de nombres
    Par sebduth dans le forum Oracle
    Réponses: 10
    Dernier message: 18/11/2005, 10h07
  5. Réponses: 4
    Dernier message: 10/06/2004, 18h05

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