Précédent   Forum des professionnels en informatique > Bases de données > Oracle > Outils > SQL*Loader
SQL*Loader Forum d'entraide sur Oracle SQL*Loader
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/08/2006, 14h56   #1
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
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.
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 15h07   #2
Futur Membre du Club
 
Étudiant
Inscription : juillet 2006
Messages : 61
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juillet 2006
Messages : 61
Points : 15
Points : 15
salut,

Code :
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
gapse est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 15h12   #3
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
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.
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 15h35   #4
Membre du Club
 
Inscription : mars 2004
Messages : 98
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 98
Points : 41
Points : 41
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.
learn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 15h39   #5
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
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 !
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 15h55   #6
Membre habitué
 
Inscription : août 2006
Messages : 181
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 181
Points : 128
Points : 128
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
Oraman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 16h04   #7
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
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.
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 17h24   #8
Nouveau Membre du Club
 
Inscription : février 2006
Messages : 28
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 28
Points : 32
Points : 32
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.
hadlak est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 17h30   #9
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
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...
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/08/2006, 23h56   #10
Nouveau Membre du Club
 
Inscription : février 2006
Messages : 28
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 28
Points : 32
Points : 32
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 :
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 :
GRANT EXECUTE ON  NEXT_ID TO TON_USER
Code :
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.
hadlak est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/08/2006, 10h47   #11
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
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 :
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 :
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.
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/08/2006, 12h50   #12
Nouveau Membre du Club
 
Inscription : février 2006
Messages : 28
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 28
Points : 32
Points : 32
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 :
    SELECT * FROM USER_INDEXES WHERE STATUS = ‘INVALID’;
hadlak est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/08/2006, 13h47   #13
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
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.
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/08/2006, 13h54   #14
Nouveau Membre du Club
 
Inscription : février 2006
Messages : 28
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 28
Points : 32
Points : 32
le commit n'est pas nécessaire pour un create.
et l'espace dans le tablespace temporaire ?
hadlak est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/08/2006, 13h56   #15
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
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 !
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/08/2006, 15h44   #16
Invité de passage
 
Inscription : juin 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 35
Localisation : France

Informations forums :
Inscription : juin 2005
Messages : 11
Points : 3
Points : 3
Effectivement, mes Tablespaces d'index et Temp sont pleins...

CQFD.

Merci à tous ceux qui m'ont répondu, et en particulier à Hadlak.
jnp87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h38.


 
 
 
 
Partenaires

Hébergement Web