2009-08-14 13 views
1

私はクエリで次の機能を持っています。整数IDでうまく動作しますが、IDがvarchar(ID:Xewi3adc)の場合は動作しません。よく私はそれがまだ仕事をする方法を知っていない、私は多くの変更を行っていますが、私はそれが仕事を得るcould'nt。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

私は試してみましたが、悲しいことにそれを試してください。私に教えてください。 – 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 

またはアカウントにフィルタを取るために階層的な機能を変更します。