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

Requête récursive est ce possible


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut Requête récursive est ce possible
    Bonjour à tous

    J'ai deux tables dans ma base de donnés qui ressemblent à celles -ci :

    Une table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Repertoire (id : number, nom:varchar, id_parent : number).
    Une autre table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Fichier (id: number, nom : varchar, repertoire_id : number).
    J'ai besoin de faire une requête qui me ramène tous les fichiers d'un répertoire de façon récursive.

    J'ai utilisé deux possibilités, mais les deux mettent plus d'une 15 secondes pour ramener un fichier .

    Les deux possibilités que j'ai utilisées sont les suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    start with ...connect by prior 
    Par programmation
    Y'a-t-il une autre façon de faire ?

    Merci de votre aide.
    Cordialement hbellahc

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 270
    Par défaut
    Connect by fonctionne tres mal avec avec des tables en jointure d'apres mon experience.
    Par contre, avec une fonction pipeline appelant elle même une procedure recursive cela marche tres bien.

    La fonction pipeline ramene une structure fonction de tes besoins.
    Elle crée un tableau correspondant a cette structure.
    Elle appelle la proc recursive avec la racine et le tableau en parametre (le tableau est passé par adresse (NO COPY))
    elle boucle pour renvoyer les lignes du tableau.

    La proc recursive
    scan le contenu du répertoire passé en parametre
    Si c'est un fichier, il est mis dans le tableau
    Si c'est un dossier la fonction s'apelle elle même avec la nouveau dossier en parametre (et le tableau bien sur).

    Tu utilise ensuite la fonction pipeline dans un select.

    J'ai recemment développé un truc du genre, cela marche du feu de dieu : moins d'un dixieme de seconde pour une nomenclature à plus de 10 niveaux et plusieurs centaines de composants).

    Ce n'est pas immédiat à coder parce qu'on utilise pas souvent ce genre de choses, mais bon...


    regarder dans la doc les fonctions pipeline, la définition des types et la gestion des "table of" en PL.

    Si tu as une boucle dans tes nomenclatures, evidemment, cela n'est pas detecté et cela dure... un temps certain dépendant de la mémoire disponible avant plantage !

    cela ne dispense pas d'avoir les bons index, des stats à jour et les bons types de données en critères dans les requêtes. (a verifier par rapport a ta solution programmée)

  3. #3
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    il faut sans doute passer par une sous-requête :

    ex:

    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
     
     
    create table Repertoire (id number primary key, nom varchar2(15), id_parent number references repertoire(id));
     
    create table Fichier (id number primary key, nom varchar(15), repertoire_id number references repertoire(id));
     
    insert into repertoire (id,nom,id_parent) values (1,'/',null);
    insert into repertoire (id,nom,id_parent) values (2,'/etc',1);
    insert into repertoire (id,nom,id_parent) values (3,'/etc/inet',2);
    insert into repertoire (id,nom,id_parent) values (4,'/usr',1);
    insert into repertoire (id,nom,id_parent) values (5,'/usr/local',4);
    insert into repertoire (id,nom,id_parent) values (6,'/usr/local/bin',5);
     
    insert into fichier(id,nom,repertoire_id) values (1,'passwd',2);
    insert into fichier(id,nom,repertoire_id) values (2,'shadow',2);
    insert into fichier(id,nom,repertoire_id) values (3,'hosts',3);
    insert into fichier(id,nom,repertoire_id) values (4,'ssh',6);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    select fichier.nom
    from fichier, (
      select repertoire.id
      from repertoire
      connect by prior repertoire.id=repertoire.id_parent
      start with repertoire.nom='/etc') rep
    where fichier.repertoire_id=rep.id
     
    NOM            
    ---------------
    shadow         
    passwd         
    hosts
    ou (merci de préciser la version)
    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
     
    select rep.repertoire, fichier.nom fichier
    from fichier, (
      select connect_by_root repertoire.nom repertoire, repertoire.id
      from repertoire
      connect by prior repertoire.id=repertoire.id_parent
      ) rep
    where fichier.repertoire_id=rep.id
    order by 1,2
     
    REPERTOIRE      FICHIER        
    --------------- ---------------
    /               hosts          
    /               passwd         
    /               shadow         
    /               ssh            
    /etc            hosts          
    /etc            passwd         
    /etc            shadow         
    /etc/inet       hosts          
    /usr            ssh            
    /usr/local      ssh            
    /usr/local/bin  ssh

  4. #4
    Membre averti
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Par défaut
    ou (merci de préciser la version).
    C'est Oracle8.

    J'ai essayé la deuxième requête ça ne passe pas.

    La première je l'utilise actuellement, mais elle est super lente.

    Merci en tous cas.

Discussions similaires

  1. Réponses: 7
    Dernier message: 20/08/2013, 19h41
  2. [AC-2007] Analyse croisée : 2 requêtes successivesN Est-ce possible ?
    Par jmlabatut dans le forum Requêtes et SQL.
    Réponses: 0
    Dernier message: 03/12/2009, 15h56
  3. Réponses: 1
    Dernier message: 30/06/2008, 17h01
  4. [SQL] Est-il possible d'afficher le résultat d'une requête dans un cadre
    Par dessinateurttuyen dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 18/07/2006, 17h52
  5. Optimiser une requête..est-ce possible ?
    Par Thierry8 dans le forum Langage SQL
    Réponses: 9
    Dernier message: 27/09/2005, 11h31

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