Bonjour à tous.
J'essaie de générer l'ordre d'insertion de données dans les tables appartenant à un utilisateur Oracle donné, en respectant les dépendances (clés étrangères).
J'ai donc créé la procédure suivante :
Mon problème c'est que le code bouffe trop de CPU (100%).
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 CREATE OR REPLACE PROCEDURE hierarchie_fk(p_owner dba_tables.owner%TYPE) IS -- Cette procédure affiche l'hiérarchie des contraintes de clés étrangère -- des tables d'un schéma Oracle donné -- Utile pour générer l'ordre d'insertion ou de suppression de données -- L'insertion doit se faire par ordre croissant de l'hierarchie obtenu -- Pour la suppression, c'est l'inverse /*create table hierarchie_fk_1 ( NOM VARCHAR2(64), HIERARCHIE NUMBER )*/ TYPE t_t_name IS TABLE OF dba_tables.table_name%TYPE; v_t_name_1 t_t_name; TYPE t_hierarchie IS TABLE OF hierarchie_fk_1.hierarchie%TYPE; v_hierarchie hierarchie_fk_1.hierarchie%TYPE; PROCEDURE reference(p_t_name dba_tables.table_name%TYPE, p_hierarchie NUMBER) IS v_t_name_2 t_t_name; BEGIN SELECT DISTINCT B1.TABLE_NAME BULK COLLECT INTO v_t_name_2 FROM ALL_CONSTRAINTS B1, ALL_CONS_COLUMNS C1 WHERE B1.R_Constraint_Name = C1.Constraint_name AND B1.R_Owner = C1.Owner AND B1.CONSTRAINT_TYPE = 'R' AND C1.Table_name = p_t_name AND C1.owner = upper(p_owner); IF v_t_name_2.COUNT > 0 THEN SELECT hierarchie INTO v_hierarchie FROM hierarchie_fk_1 WHERE nom = p_t_name; -- On ne met pas à jour la valeur de hiérarchie si il est déjà supérieur à p_hierarchie actuel IF v_hierarchie < p_hierarchie THEN UPDATE hierarchie_fk_1 SET hierarchie = p_hierarchie WHERE nom = p_t_name; COMMIT; END IF; -- Appel récursif de la procédure pour chaque nom de table obtenu FOR i IN v_t_name_2.FIRST .. v_t_name_2.LAST LOOP reference(v_t_name_2(i), p_hierarchie + 1); END LOOP; END IF; END reference; BEGIN EXECUTE IMMEDIATE 'truncate TABLE hierarchie_fk_1'; -- Liste de toutes les tables du schéma p_owner SELECT DISTINCT table_name BULK COLLECT INTO v_t_name_1 FROM dba_tables WHERE owner = upper(p_owner); IF v_t_name_1.COUNT <> 0 THEN FOR i IN v_t_name_1.FIRST .. v_t_name_1.LAST LOOP -- Initialisation de la table hierarchie_fk_1 INSERT INTO hierarchie_fk_1 VALUES (v_t_name_1(i), 0); COMMIT; END LOOP; FOR i IN v_t_name_1.FIRST .. v_t_name_1.LAST LOOP reference(v_t_name_1(i), 1); END LOOP; END IF; END hierarchie_fk;
Quelqu'un aurait-il une idée pour l'améliorer, ou bien existe t-il d'autres moyens ou outils pour réaliser ce que j'essaie de faire?
Pou information :
- Oracle 8, Windows 2000 SP2, CPU 2.4 GHz, RAM 2Go.
- L'utilisateur avec lequel j'ai effectué le test possède environ 200 tables.
Merci d'avance.
Partager