USE `vn`; DROP procedure IF EXISTS `department_calcTreeRec`; DELIMITER $$ USE `vn`$$ CREATE DEFINER=`root`@`%` PROCEDURE `department_calcTreeRec`( vSelf INT, vPath VARCHAR(255), vDepth INT, INOUT vIndex INT, OUT vSons INT ) BEGIN /** * Calculates and sets the #path, #lft, #rgt, #sons and #depth * columns for all children of the passed node. Once calculated * the last node rgt index and the number of sons are returned. * To update it's children, this procedure calls itself recursively * for each one. * * @vSelf The node identifier * @vPath The initial path * @vDepth The initial depth * @vIndex The initial lft index * @vSons The number of direct sons */ DECLARE vChildFk INT; DECLARE vLft INT; DECLARE vMySons INT; DECLARE vDone BOOL; DECLARE vChildren CURSOR FOR SELECT id FROM department WHERE (vSelf IS NULL AND parentFk IS NULL) OR (vSelf IS NOT NULL AND parentFk = vSelf); DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; SET vSons = 0; OPEN vChildren; myLoop: LOOP SET vDone = FALSE; FETCH vChildren INTO vChildFk; IF vDone THEN LEAVE myLoop; END IF; SET vIndex = vIndex + 1; SET vLft = vIndex; SET vSons = vSons + 1; CALL department_calcTreeRec( vChildFk, CONCAT(vPath, vChildFk, '/'), vDepth + 1, vIndex, vMySons ); SET vIndex = vIndex + 1; INSERT INTO tNestedTree SET id = vChildFk, path = vPath, lft = vLft, rgt = vIndex, depth = vDepth, sons = vMySons; END LOOP; CLOSE vChildren; END$$ DELIMITER ;