Page 1 sur 1

Afficher un arbres par représentation intervallaire

Posté : 03 mars 2012, 01:34
par Texicitys
Bonjour,

J'ai lu le tuto suivant: http://sqlpro.developpez.com/cours/arborescence/

Cependant, il y a une chose qui n'est pas expliquée dans ce tuto. C'est une chose certainement toute simple mais que je ne trouve pas.

Comment afficher le tableau en entier avec les feuilles et les noeux (comme ici: http://www.collaide.com/documents/liste ... aines.html ) ?

Merci d'avance

Re: Afficher un arbres par représentation intervallaire

Posté : 06 mars 2012, 17:32
par Texicitys
Sur le tuto, il y a des procédure stockée, je les ai adaptées à ma base de données et les est exécutées dans ma console SQL sur phpmyadmin. J'obtiens le message suivant:

Voilà ce que je lance:
-- procédure d'insertion dans l'arbre [Frédéric Brouard, Philippe Boucault 25/09/2002]

CREATE PROCEDURE SP_INS_DOMAINS

      @lib varchar(32),     -- le libellé à insérer
      @desc varchar(1024),  -- la description à insérer
      @id_parent int,       -- Ancêtre ou frère point d'origine de l'insertion 
      @mode char(2)         -- le mode d'insertion :
                                    -- FA : Fils Ainé,
                                    -- FC : Fils Cadet,
                                    -- GF : Grand frère,
                                    -- PF : Petit Frère,
                                    -- P  : Père
AS

 DECLARE @OK int

 DECLARE @bgp int          -- borne gauche parent
 DECLARE @bdp int          -- borne droite parent 
 DECLARE @nivp int         -- niveau parent 

 DECLARE @bgi int          -- borne gauche à insérer
 DECLARE @bdi int          -- borne droite à insérer
 DECLARE @nivi int         -- niveau à insérer

 SET NOCOUNT ON

-- gestion des effets de bord
 IF @mode IS NULL OR @lib IS NULL OR @lib = ''
 BEGIN
    RAISERROR ('Insertion impossible sans libellé ou mode ! (TABLE domains)', 16, 1)
    RETURN
 END

 SET @mode = UPPER(@mode)
 IF NOT( @mode = 'FA' OR @mode = 'FC' OR @mode = 'GF' OR @mode = 'PF'  OR @mode = 'P')
 BEGIN
    RAISERROR ('Insertion impossible, mode inconnu !', 16, 1)
    RETURN
 END

 -- démarrage transaction 
 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
 BEGIN TRANSACTION INSERT_DOMAINS
 

-- pas de parent => seul cas, table vide ou insertion d'un collatéral 
 IF @id_parent IS NULL
 BEGIN
    SELECT @OK = count(*) FROM domains
    IF @OK = 0 OR @OK IS NULL
    BEGIN
       IF @mode = 'FA' OR @mode = 'FC'
       BEGIN
          RAISERROR ('Insertion impossible dans un arbre pour un fils sans père !', 16, 1)
          GOTO LBL_ERROR
          RETURN
       END
       ELSE
       BEGIN
-- première insertion 
          INSERT INTO domains ( dom_name, dom_desc, dom_level, dom_gauche, dom_droite )
                 VALUES( @lib, @desc, 0, 1, 2 )
          IF @@ERROR <> 0
          BEGIN
             GOTO LBL_ERROR
             RETURN
          END
          COMMIT TRANSACTION INSERT_DOMAINS
          SELECT @@IDENTITY
          RETURN
       END
    END
    ELSE 
-- Insertion d'un collatéral 
    BEGIN 
       RAISERROR ('Insertion impossible dans un arbre pour un collatéral sans précision du parent !', 16, 1)
       GOTO LBL_ERROR
       RETURN
    END
 END

-- Le parent existe toujours ?
 SELECT @OK = count(*) FROM domains WHERE dom_id = @id_parent
 IF @OK = 0 OR @OK IS NULL
 BEGIN
    RAISERROR ('Insertion impossible, le parent n''existe plus !', 16, 1)
    GOTO LBL_ERROR
    RETURN
 END

-- On a un parent : on récupère ses éléments
 SELECT @bgp = dom_gauche, @bdp = dom_droite, @nivp = dom_level 
        FROM domains 
        WHERE dom_id = @id_parent

-- insertion d'un père
 IF @mode = 'P'
 BEGIN
    -- Décalage de l'ensemble colatéral droit
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite > @bdp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche > @bdp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    -- Décalalage ensemble visé vers le bas
    UPDATE domains
           SET dom_gauche = dom_gauche + 1,
               dom_droite = dom_droite + 1,
               dom_level = dom_level + 1
           WHERE dom_gauche >= @bgp AND dom_droite <= @bdp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    -- Insertion du nouveau père
    INSERT INTO domains ( dom_name, dom_desc, dom_level, dom_gauche, dom_droite )
           VALUES( @lib, @desc, @nivp, @bgp, @bdp + 2 )
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END
 END

-- Insertion d'un grand frère
 IF @mode = 'GF'
 BEGIN
    -- Limite sup.
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite > @bgp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    -- Limite inf.
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche >= @bgp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    SET @bgi = @bgp
    SET @bdi = @bgp + 1
    SET @nivi = @nivp
    INSERT INTO domains ( dom_name, dom_desc, dom_level, dom_gauche, dom_droite )
           VALUES( @lib, @desc, @nivi, @bgi, @bdi )
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END
 END
 

--  Insertion d'un petit frère 
 IF @mode = 'PF'
 BEGIN
    -- Limite sup.
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite > @bdp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    -- Limite inf.
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche >= @bdp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    SET @bgi = @bdp + 1
    SET @bdi = @bdp + 2
    SET @nivi = @nivp
    INSERT INTO domains ( dom_name, dom_desc, dom_level, dom_gauche, dom_droite )
           VALUES( @lib, @desc, @nivi, @bgi, @bdi )
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END
 END

--  Insertion d'un fils ainé
 IF @mode = 'FA'
 BEGIN
    -- Limite sup.
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite > @bgp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    -- Limite inf.
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche > @bgp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    SET @bgi = @bgp + 1
    SET @bdi = @bgp + 2
    SET @nivi = @nivp + 1
    INSERT INTO domains ( dom_name, dom_desc, dom_level, dom_gauche, dom_droite )
           VALUES( @lib, @desc, @nivi, @bgi, @bdi )
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END
 END

--  Insertion d'un fils cadet
 IF @mode = 'FC'
 BEGIN
    -- Limite sup.
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite >= @bdp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    -- Limite inf.
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche > @bdp
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END

    SET @bgi = @bdp
    SET @bdi = @bdp + 1
    SET @nivi = @nivp + 1
    INSERT INTO domains ( dom_name, dom_desc, dom_level, dom_gauche, dom_droite )
           VALUES( @lib, @desc, @nivi, @bgi, @bdi )
    IF @@ERROR <> 0
    BEGIN
       GOTO LBL_ERROR
       RETURN
    END
 END

-- renvoi de l'identifiant de l'élément inséré
 SELECT @@IDENTITY

 COMMIT TRANSACTION INSERT_DOMAINS
 RETURN

 LBL_ERROR:
 ROLLBACK TRANSACTION INSERT_DOMAINS
Voici le message d'erreur:

Code : Tout sélectionner

#1064 - You have an error in your SQL [code]syntax
; check the manual that corresponds to your MySQL server version for the right syntax to use near '@lib varchar(32), -- le libellé à insérer @desc varchar(1024), --' at line 5[/code]

Ou sinon, j'essaie ça :
CREATE VIEW v_domains
AS
SELECT dom_id, CAST(SPACE(dom_level)+ dom_name AS VARCHAR(64)) AS dom_name,
       dom_level, dom_gauche, dom_droite,
       (SELECT COUNT(*)
        FROM   domains T2
        WHERE  T2.dom_gauche > T1.dom_gauche
          AND  T2.dom_droite < T1.dom_droite) AS NMC_NBR_DESCENDANT,
       dom_desc 
FROM   domains T1
J'obtiens ça :

Code : Tout sélectionner

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VARCHAR(64)) AS dom_name, dom_level, dom_gauche, dom_droite, (SE' at line 3
J'avoue ne pas trop m'y connaitre en procédure préparée..

Merci d'avance

Re: Afficher un arbres par représentation intervallaire

Posté : 07 mars 2012, 16:42
par Texicitys
En fait, les procédure stockée sont pour microsoft sql server, je ne connais pas du tout..

Comment puis-je les changer pour mysql?

Merci beaucoup

Re: Afficher un arbres par représentation intervallaire

Posté : 08 mars 2012, 17:32
par Texicitys
Bonjour à vous!

En fait la procédure stockée etait pour microsoft SQL server.

J'ai essayer de la convertire mais j'ai quelques problèmes voici ou j'en suis :
DELIMITER $$

 CREATE PROCEDURE SP_INS_DOMAINS 
	(
      lib VARCHAR(32),     -- le libellé à insérer
      description VARCHAR(1024),  -- la description à insérer
      id_parent int,       -- Ancêtre ou frère point d'origine de l'insertion 
      mode_insert VARCHAR(2)         -- le mode d'insertion :
                                    -- FA : Fils Ainé,
                                    -- FC : Fils Cadet,
                                    -- GF : Grand frère,
                                    -- PF : Petit Frère,
                                    -- P  : Père
	)
	BEGIN
	
DECLARE ok int;
 
 DECLARE bgp int ;         -- borne gauche parent
 DECLARE bdp int ;         -- borne droite parent 
 DECLARE nivp int  ;       -- niveau parent 
 
 DECLARE bgi int  ;        -- borne gauche à insérer
 DECLARE bdi int ;         -- borne droite à insérer
 DECLARE nivi int  ;       -- niveau à insérer

 -- SET NOCOUNT ON
 
 -- gestion des effets de bord
IF mode_insert IS NULL OR lib IS NULL OR lib = '' THEN

    --RAISERROR ('Insertion impossible sans libellé ou mode ! (TABLE domains)', 16, 1)
    -- RETURN
END IF;

-- Test du mode_insert
SET mode_insert = UPPER(mode_insert);
 IF NOT( mode_insert = 'FA' OR mode_insert = 'FC' OR mode_insert = 'GF' OR mode_insert = 'PF'  OR mode_insert = 'P') THEN
 
    -- RAISERROR ('Insertion impossible, mode inconnu !', 16, 1)
    -- RETURN
 END IF;
 
 -- démarrage transaction 
 -- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
 -- BEGIN TRANSACTION INSERT_DOMAINS
 
 -- pas de parent => seul cas, table vide ou insertion d'un collatéral 
 IF id_parent IS NULL THEN
 
    SELECT ok = count(*) FROM domains ;
    IF ok = 0 OR ok IS NULL THEN
       IF mode_insert = 'FA' OR mode_insert = 'FC' THEN
          -- RAISERROR ('Insertion impossible dans un arbre pour un fils sans père !', 16, 1)
          GOTO LBL_ERROR
          -- RETURN
       ELSE
		-- première insertion 
          INSERT INTO domains ( dom_name, dom_description, dom_level, dom_gauche, dom_droite )
                 VALUES( lib, description, 0, 1, 2 ) ;
          IF @@ERROR <> 0 THEN
             GOTO LBL_ERROR
             -- RETURN
          END IF ;
          -- COMMIT TRANSACTION INSERT_DOMAINS
          SELECT @@IDENTITY
          -- RETURN
       END IF ;
    ELSE 
-- Insertion d'un collatéral  
       -- RAISERROR ('Insertion impossible dans un arbre pour un collatéral sans précision du parent !', 16, 1)
       GOTO LBL_ERROR
       -- RETURN
	END IF;

-- On a un parent : on récupère ses éléments
 SELECT @bgp = dom_gauche, @bdp = dom_droite, @nivp = dom_level 
        FROM domains 
        WHERE dom_id = id_parent ;
 
-- insertion d'un père
 IF mode_insert = 'P' THEN
    -- Décalage de l'ensemble colatéral droit
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite > @bdp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche > @bdp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    -- Décalalage ensemble visé vers le bas
    UPDATE domains
           SET dom_gauche = dom_gauche + 1,
               dom_droite = dom_droite + 1,
               dom_level = dom_level + 1
           WHERE dom_gauche >= @bgp AND dom_droite <= @bdp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    -- Insertion du nouveau père
    INSERT INTO domains ( dom_name, dom_description, dom_level, dom_gauche, dom_droite )
           VALUES( lib, description, @nivp, @bgp, @bdp + 2 ) ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 END IF;
 
-- Insertion d'un grand frère
 IF mode_insert = 'GF' THEN
    -- Limite sup.
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite > @bgp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    -- Limite inf.
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche >= @bgp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    SET @bgi = @bgp ;
    SET @bdi = @bgp + 1 ;
    SET @nivi = @nivp ;
    INSERT INTO domains ( dom_name, dom_description, dom_level, dom_gauche, dom_droite )
           VALUES( lib, description, @nivi, @bgi, @bdi ) ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 END IF;
 
 
--  Insertion d'un petit frère 
 IF mode_insert = 'PF' THEN
    -- Limite sup.
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite > @bdp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    -- Limite inf.
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche >= @bdp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    SET @bgi = @bdp + 1 ;
    SET @bdi = @bdp + 2 ;
    SET @nivi = @nivp ;
    INSERT INTO domains ( dom_name, dom_description, dom_level, dom_gauche, dom_droite )
           VALUES( lib, description, @nivi, @bgi, @bdi ) ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 END IF;
 
--  Insertion d'un fils ainé
 IF mode_insert = 'FA' THEN
    -- Limite sup.
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite > @bgp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    -- Limite inf.
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche > @bgp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    SET @bgi = @bgp + 1 ;
    SET @bdi = @bgp + 2 ;
    SET @nivi = @nivp + 1 ;
    INSERT INTO domains ( dom_name, dom_description, dom_level, dom_gauche, dom_droite )
           VALUES( lib, description, @nivi, @bgi, @bdi );
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 END IF;
 
--  Insertion d'un fils cadet
 IF mode_insert = 'FC' THEN
    -- Limite sup.
    UPDATE domains
           SET dom_droite = dom_droite + 2
           WHERE dom_droite >= @bdp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    -- Limite inf.
    UPDATE domains
           SET dom_gauche = dom_gauche + 2
           WHERE dom_gauche > @bdp ;
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 
    SET @bgi = @bdp ;
    SET @bdi = @bdp + 1 ;
    SET @nivi = @nivp + 1 ;
    INSERT INTO domains ( dom_name, dom_description, dom_level, dom_gauche, dom_droite )
           VALUES( lib, description, @nivi, @bgi, @bdi );
    IF @@ERROR <> 0 THEN
       GOTO LBL_ERROR
       -- RETURN
    END IF;
 END IF;
 
-- renvoi de l'identifiant de l'élément inséré
 SELECT @@IDENTITY
 
 -- COMMIT TRANSACTION INSERT_DOMAINS
 -- RETURN
 
 LBL_ERROR:
 -- ROLLBACK TRANSACTION INSERT_DOMAINS
 
END$$
DELIMITER ;
Cependant, j'ai toujours un message d'erreur au début :
MySQL a répondu: Documentation
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 15
La ligne 15 est le BEGIN...

Je pense avoir quand même bien changé la fonction.. maintenant il faut encore trouver les erreurs et compléter :)

Merci d'avance

Re: Afficher un arbres par représentation intervallaire

Posté : 20 janv. 2014, 13:11
par Ezelorf
Salut Texicitys,
Je relance ton sujet car j'ai actuellement le meme probleme que toi.
A tu solutionné ton problème et comment?
Sinon quelqu'un à t il une idée?

Re: Afficher un arbres par représentation intervallaire

Posté : 21 janv. 2014, 13:20
par Cyrano
Compte bien les « IF » et les « END IF » correspondants : tu verras qu'il en manque peut-être des bouts quelque part.

Une bonne indentation dans le code SQL, ça peut aider pas mal.