2009-08-14 5 views
1

나는 쿼리와 함께 다음과 같은 기능을 가지고 있습니다. 그것은 정수 ID와 함께 잘 작동하지만, ID가 varchar (ID : Xewi3adc)이면 작동하지 않습니다. 글쎄, 내가 어떻게 작동하는지 알지 못한다. 나는 많은 수정을하고있다. 그러나 나는 그것을 얻을 수 없다.SQL 복잡한 트리 행

DROP FUNCTION IF EXISTS album_tree_connect; 

DELIMITER $$ 

CREATE FUNCTION album_tree_connect(value varchar(32)) RETURNS INT 
NOT DETERMINISTIC 
READS SQL DATA 
BEGIN 
    DECLARE _id varchar(32); 
    DECLARE _parent varchar(32); 
    DECLARE _next INT; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL; 

    SET _parent = @id; 
    SET _id = -1; 

    IF @id IS NULL THEN 
     RETURN NULL; 
    END IF; 

    LOOP 
     SELECT MIN(album_id) 
     INTO @id 
     FROM album 
     WHERE sub_album_of_album_id = _parent 
      AND album_id > _id; 
     IF @id IS NOT NULL OR _parent = @start_with THEN 
      SET @level = @level + 1; 
      RETURN @id; 
     END IF; 
     SET @level := @level - 1; 
     SELECT album_id, sub_album_of_album_id 
     INTO _id, _parent 
     FROM album 
     WHERE album_id = _parent; 
    END LOOP; 
END 
$$ 

DELIMITER ; 


## select statement to pull the tree menu 

SELECT CONCAT(REPEAT(' ', level - 1), CAST(hi.album_id AS CHAR)) AS treeitem, sub_album_of_album_id, name, user_id, level 
FROM (
     SELECT album_tree_connect(album_id) AS id, @level AS level 
     FROM (
       SELECT @start_with := 0, 
         @id := @start_with, 
         @level := 0 
       ) vars, album 
     WHERE @id IS NOT NULL 
     ) ho 
JOIN album hi 
ON  hi.album_id = ho.id 
where user_id = 2 

답변

3

함수 리턴 유형은 INT로 선언되므로 리턴 값은 해당 유형으로 강제 변환됩니다. 돌려 주어지는 값 (album_id 필드)가 정수가 아닌 경우, 값이 변경 될 가능성이 있습니다. http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html

+0

나는 시험해 보았다.하지만 슬프게도 didnt는 일한다. 당신은 그것을 시험해보고, 말해 줄 수있다. .. 당신이 원한다면 나는 당신에게 빠른 SQL 덤프를 줄 수있다. – Basit

1

첫째, GApple이 제안 함수 선언을 수정 :

CREATE FUNCTION album_tree_connect(value varchar(32)) RETURNS VARCHAR(32) 

둘째, 초기 _id는 emtpy 문자열로 초기화해야하지 -1 :

SET _id = ''; 

셋째, 당신의 @start_with 문자열 (부모 노드 식별자로 사용되는 문자열)로 초기화해야합니다.

SELECT CONCAT(REPEAT(' ', level - 1), 
     CAST(hi.album_id AS CHAR)) AS treeitem, sub_album_of_album_id, name, user_id, level 
FROM (
     SELECT album_tree_connect(album_id) AS id, @level AS level 
     FROM (
       SELECT @start_with := '0', 

         --- The '0' above should be a string. 

         @id := @start_with, 
         @level := 0 
       ) vars, album 
     WHERE @id IS NOT NULL 
     ) ho 
JOIN album hi 
ON  hi.album_id = ho.id 

위의 쿼리에서 user_id의 필터는 대부분 잘못 작동합니다.

당신은 하위 쿼리에 기능을 포장 중 하나가 필요합니다

SELECT * 
FROM (
     SELECT CONCAT(REPEAT(' ', level - 1), 
       CAST(hi.album_id AS CHAR)) AS treeitem, sub_album_of_album_id, name, user_id, level 
     FROM (
       SELECT album_tree_connect(album_id) AS id, @level AS level 
       FROM (
         SELECT @start_with := '0', 

           --- The '0' above should be a string. 

           @id := @start_with, 
           @level := 0 
         ) vars, album 
       WHERE @id IS NOT NULL 
       ) ho 
     JOIN album hi 
     ON  hi.album_id = ho.id 
     ) q 
WHERE user_id = 2 

또는 계정에 필터를 취할 수있는 계층 기능을 수정합니다.