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

PL/SQL Oracle Discussion :

Génération de l'ordre d'insertion en respectant les contraintes de clés étrangères


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de ilalaina
    Homme Profil pro
    Inscrit en
    Mai 2007
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2007
    Messages : 341
    Par défaut Génération de l'ordre d'insertion en respectant les contraintes de clés étrangères
    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 :
    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;
    Mon problème c'est que le code bouffe trop de CPU (100%).
    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.

  2. #2
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    remplace les tableaux par des tables temporaires (TEMPORARY TABLE) ça devrait aller nettement mieux

  3. #3
    Membre éclairé Avatar de ilalaina
    Homme Profil pro
    Inscrit en
    Mai 2007
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2007
    Messages : 341
    Par défaut
    remplace les tableaux par des tables temporaires (TEMPORARY TABLE) ça devrait aller nettement mieux
    Voulez-vous dire remplacer v_t_name_1 et v_t_name_2 par des tables temporaires?

  4. #4
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    oui ou mieux, utiliser des curseurs

  5. #5
    Membre éclairé Avatar de ilalaina
    Homme Profil pro
    Inscrit en
    Mai 2007
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2007
    Messages : 341
    Par défaut
    J'ai utilisé des curseurs mais ça n'a pas changé grand chose, le CPU est toujours à 100%.
    En ce qui concerne les tables temporaires je ne vois pas trop comment adapter mon code, pourriez-vous m'éclairer un peu?
    Merci.

  6. #6
    Membre éclairé Avatar de ilalaina
    Homme Profil pro
    Inscrit en
    Mai 2007
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2007
    Messages : 341
    Par défaut
    Je crois qu'un DBA a souvent besoin d'une requête de ce genre, je ne comprends pas pourquoi ce n'est pas incorporé dans les différents outils d'administration. Ou es-ce moi qui n'ai pas bien cherché?

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

Discussions similaires

  1. [Débutant] Souci insertion dans une table contenant 2 clés étrangères MySql/C#
    Par Mac Chouffe dans le forum C#
    Réponses: 15
    Dernier message: 17/06/2015, 17h29
  2. Réponses: 17
    Dernier message: 03/08/2013, 13h29
  3. Syntaxe tableaux dans ordre SQL INSERT
    Par lio33 dans le forum SQL
    Réponses: 6
    Dernier message: 19/10/2005, 18h07
  4. Réponses: 11
    Dernier message: 17/01/2005, 17h58
  5. Contraintes de clés étrangères non respectées
    Par parfait dans le forum Requêtes
    Réponses: 7
    Dernier message: 28/07/2004, 13h48

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