使用while循环选择的MySQL存储函数

使用while循环选择的MySQL存储函数,mysql,stored-functions,Mysql,Stored Functions,这是我第一次编写MySQL存储函数,但我发现我做错了什么: 这是我的表格和功能: mysql> select * from PathNames; +-----+--------+-----+ | NID | Name | PID | +-----+--------+-----+ | 1 | / | 1 | | 6 | US | 1 | | 7 | TX | 6 | | 8 | Dallas | 7 | | 9 | Plano

这是我第一次编写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);

我希望
选择NID2PathName(10)
返回
“/US/TX/Frisco”
,但我只得到
“/”
。任何帮助都将不胜感激

您需要消除列名与参数名和变量名之间的歧义

例如,在这一行中,您使用相同的名称“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 ;

当id>1时,您的逻辑没有意义。如果你只想得到一个值,为什么要做一个循环呢?非常感谢你的建议。从现在起我将遵循这个惯例。谢谢我还添加了这个选项来处理SELECT返回NULL的情况<代码>为未找到的集合声明继续处理程序v_id:=0