创建mysql函数

bwntbbo3  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(281)

我正在尝试编写一个函数,在父子树中查找分配给其配置的值,如果该值为null或为空,它将查找上一级的值。我当前在尝试创建函数时遇到语法错误。这就是我目前所知道的,

DELIMITER //
CREATE FUNCTION `db`.`Configuration`(
    `ColumnName` VARCHAR(128),
    `CID` INT
)
RETURNS VARCHAR(256)
NOT DETERMINISTIC
BEGIN
    DECLARE Config VARCHAR(256) DEFAULT NULL;
    DECLARE Parent INT;

    WHILE (@Config IS NULL OR @Config = "") DO
        SELECT @ColumnName INTO @Config, `ParentID` INTO @Parent FROM `Table` WHERE `ID`=@CID;
    END WHILE;

    RETURN CONCAT(@Config, '::', @Parent);
    END ;
//
DELIMITER ;

尝试添加函数时出现以下错误:

1327-未声明的变量:parentid

任何帮助都将不胜感激!

j1dl9f46

j1dl9f461#

您收到问题中的错误消息,因为您有多个 into 子句,而根据mysql手册中的select。。。变成。。。你只能有一个。因此,要消除此特定错误消息,您需要将select语句重写为:

SELECT @ColumnName, `ParentID` INTO @Config, @Parent FROM `Table` WHERE `ID`=@CID;

但是,您的代码还有一些问题: varname 以及 @varname 不要引用同一个变量。第一个是函数/存储过程参数或局部变量,而第二个是用户定义的变量。在代码中,必须删除 @ 从变量名。
在sql语句中不能使用变量代替字段名。必须将动态sql与准备好的语句一起使用才能实现这一点。关于如何做到这一点,请参见下面的问题:如何在mysql存储过程中使用动态sql
不覆盖 CID while循环中的参数。这意味着,如果第一次迭代配置将保持为空,那么您将有一个无限循环。你应该改变 CID 在你的圈子里。
我不能保证你的代码中没有更多的错误。

cqoc49vn

cqoc49vn2#

您的功能有一些问题:
您正在使用 SELECT...INTO 不正确。选择多个值时,应仅使用 INTO 一次。例如 SELECT a,b into @a,@b FROM... 您使用的是与函数参数同名的用户定义变量,但它们不是一回事。在你的代码里 CID 以及 @CID 它们是不同的。我建议使用标准的命名前缀来澄清这一点:例如使用 p_ 函数参数和 v_ 对于局部函数变量。您根本不需要使用用户定义的变量。
你的 WHILE 循环必然导致无限循环,因为查询条件从不改变。如果它只返回一次null或空字符串,它将一直返回它们。
这里有一个快速重写,以解决上述问题。我让你来执行这个计划 WHILE 正确循环:

DELIMITER //
CREATE FUNCTION `db`.`Configuration`(
    p_column_name VARCHAR(128),
    p_id INT
)
RETURNS VARCHAR(256)
READS SQL DATA
BEGIN
    DECLARE v_config VARCHAR(256) DEFAULT NULL;
    DECLARE v_parent INT;

    SELECT p_column_name,`ParentID` 
    INTO v_config, v_parent 
    FROM `Table` 
    WHERE `ID`=p_id;

    RETURN CONCAT(v_config, '::', v_parent);
    END ;
//
DELIMITER ;

相关问题