2010-11-09 3 views
0

J'ai besoin d'aide ici.Besoin d'aide pour créer une procédure

Ma table est

CREATE TABLE `users` (
    `id` bigint(11) NOT NULL auto_increment, 
    `point` bigint(11) NOT NULL, 
    `lefth` bigint(11) NOT NULL, 
    `righth` bigint(11) NOT NULL, 
    `referel` bigint(11) NOT NULL, 
    `dateadded` timestamp NOT NULL default CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=21 ; 

données

INSERT INTO `users` VALUES (1, 1000, 2, 4, 1, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (2, 0, 3, 5, 1, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (3, 0, 6, 9, 1, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (4, 0, 14, 7, 1, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (5, 0, 8, 0, 2, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (6, 0, 0, 0, 3, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (7, 0, 15, 19, 4, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (8, 0, 10, 11, 5, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (9, 0, 0, 0, 3, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (10, 0, 0, 0, 8, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (11, 0, 12, 13, 8, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (12, 0, 0, 0, 11, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (13, 0, 0, 0, 11, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (14, 0, 16, 17, 4, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (15, 0, 0, 0, 7, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (16, 0, 0, 0, 4, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (17, 0, 0, 18, 14, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (18, 0, 0, 0, 17, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (19, 0, 20, 0, 7, '0000-00-00 00:00:00'); 
INSERT INTO `users` VALUES (20, 0, 0, 0, 19, '0000-00-00 00:00:00'); 

Je veux écrire une procédure en fournir une valeur en tant que paramètre renverra toutes les valeurs forment la table qui est à venir sous la paramètre passé.

quelque chose comme ça

DELIMITER $$ 
-- 
CREATE DEFINER=`root`@`localhost` PROCEDURE `emp_heir`(
     IN param1 INTEGER(11) 
    ) 
BEGIN 
select lefth from users where id = param1; 
END$$ 

Ceci renvoie la valeur dans la lefth colonne, mais si la valeur lefth est d'avoir des valeurs de l'enfant (valeurs en lefth et righth de cet identifiant) il doit retourner que aussi . Comme sage, il devrait continuer jusqu'à la fin de la table.

Comment cela peut-il être fait?

Merci

+0

Pourriez-vous s'il vous plaît corriger la mise en forme de votre question? – Bobby

Répondre

0

c'est ce que vous voulez?

DELIMITER $$ 

CREATE PROCEDURE my(
    IN number INT, 
    OUT lefte INT, 
    OUT righte INT 

) 
BEGIN 
    SELECT lefth, righth 
    FROM users WHERE id = number INTO lefte , righte; 

END; 

$$ 

DELIMITER ; 

l'appel est comme:

CALL my(4,@lefth,@righth); 
SELECT @lefth,@righth; 
0
CREATE DEFINER=`root`@`localhost` PROCEDURE `emp_heir` (IN param1 INTEGER(11)) 
BEGIN 
    DECLARE lh INT(11); 
    DECLARE rh INT(11); 
    DECLARE lresult VARCHAR(255) default ''; 
    DECLARE rresult VARCHAR(255) default ''; 
    SET lh := param1; 
    SET rh := param1; 
    REPEAT 
     SELECT lefth FROM users WHERE id = lh INTO lh; 
     SET lresult := CONCAT(lresult, lh, ','); 
    UNTIL lh = 0 END REPEAT; 
    REPEAT 
     SELECT righth FROM users WHERE id = rh INTO rh; 
     SET rresult := CONCAT(rresult, rh, ','); 
    UNTIL rh = 0 END REPEAT; 
    SELECT LEFT(lresult, LENGTH(lresult) - 3) AS lefths, LEFT(rresult, LENGTH(rresult) - 3) AS righths; 
END$$ 

Avez-vous Méen quelque chose comme ça? Cette procédure obtient récursivement toutes les valeurs lefth et righth et le place dans des chaînes séparées.

+0

Merci. Cela a presque fonctionné.Mais une fois que le huitième ou le cinquième du paramètre passé est récupéré, alors il doit aller chercher les valeurs de droite et de gauche de l'enfant. – zamil

+0

J'ai changé la requête en this'BEGIN DECLARE lh INT (11); DÉCLARER rh INT (11); DECLARE lresult VARCHAR (255) par défaut ''; DECLARE rresult VARCHAR (255) par défaut ''; SET lh: = param1; SET rh: = param1; REPEAT SÉLECTIONNER lefth, right FROM utilisateurs WHERE id = lh ou id = rh INTO lh, rh; SET lresult: = CONCAT (lresult, lh, ',', rh, ','); JUSQU'à hh = 0 et rh = 0 END REPEAT; CHOISIR À GAUCHE (lresult, LENGTH (lresult) - 3) AS lefths; END 'mais cela donne une erreur' résultat consisited de plus d'une ligne ' – zamil

+0

C'est vrai, 'SELECT ... INTO ...' ne peut pas fonctionner avec plus d'une ligne. – rMX

1
CREATE DEFINER=`root`@`localhost` PROCEDURE `emp_heir` (IN param1 INTEGER(11), INOUT lResult VARCHAR(255), INOUT rResult VARCHAR(255)) 
BEGIN 
    DECLARE lh INT(11); 
    DECLARE rh INT(11); 

    IF lResult IS NULL THEN 
     SET lResult := ''; 
    END IF; 
    IF rResult IS NULL THEN 
     SET rResult := ''; 
    END IF; 

    SELECT lefth, righth FROM users where id = param1 INTO lh, rh; 

    IF lh != 0 THEN 
     SET lResult := CONCAT(lResult, lh, ','); 
    END IF; 
    IF rh != 0 THEN 
     SET rResult := CONCAT(rResult, rh, ','); 
    END IF; 

    IF lh != 0 THEN 
     CALL emp_heir(lh, lResult, rResult); 
    END IF; 
    IF rh != 0 THEN 
     CALL emp_heir(rh, lResult, rResult); 
    END IF; 
END$$ 

Vérifiez cela. Pour tester:

call emp_heir(2, @lresult, @rresult, 0); 
select @lresult, @rresult; 

Juste intéressant, pourquoi ne pas le faire dans l'application? =)

UPD

Si vous obtenez une erreur sur ce point, exécuter

SET max_sp_recursion_depth = 10; 

Si l'erreur apparaît à nouveau, essayez d'augmenter la valeur

+0

ceci s'exécute correctement. Mais pas le résultat montre – zamil

+0

Hmm .. J'ai exécuté ceci sur des données de votre question et j'ai eu + -------------- + ------ ------ + | @lresult | @rresult | + -------------- + ------------ + | 3,6,8,10,12, | 5,9,11,13, | + -------------- + ------------ + – rMX

+0

ouais je l'ai maintenant. auparavant, j'utilisais sql manager 2010. J'ai obtenu le résultat quand je l'ai exécuté depuis phpmyadmin.ce n'est pas le résultat que je cherchais. si je donne 2 comme valeur initiale, le lresult shud contient 3,6,9 et le résultat devrait contenir 5,8,10,11,12,13. Je l'essaie moi-même, mais pas de chance – zamil

Questions connexes