这是我第一次编写MySQL存储功能,但我遇到问题,看看我做错了什么:
这是我的表和功能:
mysql> select * from PathNames;
+-----+--------+-----+
| NID | Name | PID |
+-----+--------+-----+
| 1 | / | 1 |
| 6 | US | 1 |
| 7 | TX | 6 |
| 8 | Dallas | 7 |
| 9 | Plano | 7 |
| 10 | Frisco | 7 |
+-----+--------+-----+
DROP FUNCTION IF EXISTS NID2PathName;
DELIMITER //
CREATE FUNCTION NID2PathName(nid INT UNSIGNED)
RETURNS TEXT DETERMINISTIC
BEGIN
DECLARE rtn TEXT;
DECLARE str TEXT;
DECLARE tmp TEXT;
DECLARE id INT UNSIGNED;
DECLARE pid INT UNSIGNED;
SET id = nid;
SET rtn = "";
SET str = "";
SET tmp = "";
WHILE id > 1 DO
SELECT Name, PID into str, pid FROM PathNames WHERE NID=id LIMIT 1;
SET rtn = CONCAT('/', str, rtn);
set id = pid;
END WHILE;
RETURN rtn;
END//
DELIMITER ;
SELECT NID2PathName(10);
我希望SELECT NID2PathName(10)
返回"/US/TX/Frisco"
,但我只获得"//"
。任何帮助将非常感谢。
答案 0 :(得分:2)
您需要从参数和变量名称中消除列名的歧义。
例如,在这一行中,您使用相同的名称“pid”来引用变量和表列,并且MySQL的行为不符合您的要求:
SELECT Name, PID into str, pid FROM PathNames WHERE NID=id LIMIT 1;
我喜欢为参数名称使用前缀p_
,为变量名称使用v_
,以保证变量名称和参数名称不会与列名称冲突。
这是你的函数用该约定重写的。它应该适合你:
DROP FUNCTION IF EXISTS NID2PathName;
DELIMITER //
CREATE FUNCTION NID2PathName(p_nid INT UNSIGNED)
RETURNS TEXT DETERMINISTIC
BEGIN
DECLARE v_rtn TEXT;
DECLARE v_str TEXT;
DECLARE v_tmp TEXT;
DECLARE v_id INT UNSIGNED;
DECLARE v_pid INT UNSIGNED;
SET v_id := p_nid;
SET v_rtn := "";
SET v_str := "";
SET v_tmp := "";
WHILE v_id > 1 DO
SELECT Name, PID into v_str, v_pid FROM PathNames WHERE NID=v_id LIMIT 1;
SET v_rtn := CONCAT('/', v_str, v_rtn);
set v_id := v_pid;
END WHILE;
RETURN v_rtn;
END//
DELIMITER ;