Bonjour,
Voici mon cas.
Je reçois un fichier contenant des données de produits de la forme suivente (je simplifie le fichier et ma table pour que ce soit + lisible car le fichier a normalement 35 champs et la table 44 champs).
Code : Sélectionner tout - Visualiser dans une fenêtre à part code produit|nom produit|type de colis|longueur|largeur|Voici un tableau qui permet de mieux visualiser les données (sachant que ce n'est qu'une représentation, pas une table de travail) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 ABC|blabla|1|15|21| ABC|blabla|2|17|13| ABC|blabla|3|5|11| PLO|plouplouf|1|40|54| PLO|plouplouf|2|38|48| PLO|plouplouf|3|42|59|
Voici la table que je souhaite remplir :
NB : DAT_TRAIT est rempli par un trigger qui avant chaque INSERT dans la table insère "systimestamp".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 TABLE_PRODUITS ( DAT_TRAIT timestamp NOT NULL, PRO_CODE varchar2(17) NOT NULL, PRO_LIB varchar2(70), LENGTH_1 number(12,3), LENGTH_2 number(12,3), LENGTH_3 number(12,3), WIDTH_1 number(12,3), WIDTH_2 number(12,3), WIDTH_3 number(12,3) )
Et le résultat que je souhaite obtenir (1 seule ligne par produit) :
J'ai donc écrit le fichier de contrôle 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
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
42
43
44 LOAD DATA INFILE '/my_data.dat' BADFILE '/my_data.bad' APPEND PRESERVE BLANKS -- COLIS 1 INTO TABLE TABLE_PRODUITS when TYPE_COLIS = '1' FIELDS TERMINATED BY '|' TRAILING NULLCOLS ( PRO_CODE "upper(trim(:PRO_CODE))", PRO_LIB "upper(trim(:PRO_LIB))", TYPE_COLIS FILLER, LENGTH_1 nullif LENGTH_1='0' "replace(:LENGTH_1, ',', '.')", WIDTH_1 nullif WIDTH_1='0' "replace(:WIDTH_1, ',', '.')" ) -- COLIS 2 INTO TABLE TABLE_PRODUITS when TYPE_COLIS = '2' FIELDS TERMINATED BY '|' TRAILING NULLCOLS ( PRO_CODE "upper(trim(:PRO_CODE))", PRO_LIB "upper(trim(:PRO_LIB))", TYPE_COLIS FILLER, LENGTH_2 nullif LENGTH_2='0' "replace(:LENGTH_2, ',', '.')", WIDTH_2 nullif WIDTH_2='0' "replace(:WIDTH_2, ',', '.')" ) -- COLIS 3 INTO TABLE TABLE_PRODUITS when TYPE_COLIS = '3' FIELDS TERMINATED BY '|' TRAILING NULLCOLS ( PRO_CODE "upper(trim(:PRO_CODE))", PRO_LIB "upper(trim(:PRO_LIB))", TYPE_COLIS FILLER, LENGTH_3 nullif LENGTH_3='0' "replace(:LENGTH_3, ',', '.')", WIDTH_3 nullif WIDTH_3='0' "replace(:WIDTH_3, ',', '.')" )
Actuellement avec ce fichier de contrôle j'obtiens cela :
Je sais qu'il faut utiliser "POSITION(x:y)" pour que SQL Loader reparcoure les enregistrements depuis le début.
J'ai donc ajouté POSITION(1:3)au champ PRO_CODE comme suit
Code : Sélectionner tout - Visualiser dans une fenêtre à part PRO_CODE POSITION(1:3) "upper(trim(:PRO_CODE))" ,
Mais cela n'a rien changé.
Par divers tests sur des tables d'exemple (voir ce topic) j'ai cru comprendre qu'il fallait que le POSITION(x:y) concerne le champ de la clause WHEN.
Déjà, est ce que cette constatation est vraie ?
Si oui, je ne peux pas mettre "POSITION(x:y)" au champ TYPE_COLIS car certains champs précédant TYPE_COLIS (notamment PRO_LIB) sont de longueur variable !
J'ai donc penser à ajouter une clause au when comme suit :
Mais j'ai testé, cela ne fonctionne pas mieux, j'obtiens toujours le même résultat.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 when TYPE_COLIS = '3' and PRO_CODE <> '000000' -- (ou PRO_CODE not null, je ne sais pas la syntaxe)
Dans les logs, je vois que SQLLoader plante sur un champ que je ne vous ai pas mis (ORA-01401: inserted value too large for column) alors que la colonne est un varchar2(3) et qua la valeur à insérer est "01"...
C'est idem en mettant la clause sur le PRO_CODE en premier ..
Est-ce que qqun pourrait m'aider ?
D'avance merci !
Partager