黑脸艺术家 发表于 2023-6-14 15:44:01

在MySQL中输入提示三次错误??

题目是:创建一个函数show_sign,函数的功能是,当向函数传递一个出生日期参数时,函数返回其所属的星座名称;


CREATE FUNCTION show_sign(birthday DATE)
RETURNS VARCHAR(20)
BEGIN
    DECLARE sign_name VARCHAR(20);   这里提示出错!!!
    SET sign_name = CASE
      WHEN (MONTH(birthday) = 3 AND DAY(birthday) >= 21) OR (MONTH(birthday) = 4 AND DAY(birthday) <= 19) THEN '白羊座'
      WHEN (MONTH(birthday) = 4 AND DAY(birthday) >= 20) OR (MONTH(birthday) = 5 AND DAY(birthday) <= 20) THEN '金牛座'
      WHEN (MONTH(birthday) = 5 AND DAY(birthday) >= 21) OR (MONTH(birthday) = 6 AND DAY(birthday) <= 21) THEN '双子座'
      WHEN (MONTH(birthday) = 6 AND DAY(birthday) >= 22) OR (MONTH(birthday) = 7 AND DAY(birthday) <= 22) THEN '巨蟹座'
      WHEN (MONTH(birthday) = 7 AND DAY(birthday) >= 23) OR (MONTH(birthday) = 8 AND DAY(birthday) <= 22) THEN '狮子座'
      WHEN (MONTH(birthday) = 8 AND DAY(birthday) >= 23) OR (MONTH(birthday) = 9 AND DAY(birthday) <= 22) THEN '处女座'
      WHEN (MONTH(birthday) = 9 AND DAY(birthday) >= 23) OR (MONTH(birthday) = 10 AND DAY(birthday) <= 23) THEN '天秤座'
      WHEN (MONTH(birthday) = 10 AND DAY(birthday) >= 24) OR (MONTH(birthday) = 11 AND DAY(birthday) <= 22) THEN '天蝎座'
      WHEN (MONTH(birthday) = 11 AND DAY(birthday) >= 23) OR (MONTH(birthday) = 12 AND DAY(birthday) <= 21) THEN '射手座'
      WHEN (MONTH(birthday) = 12 AND DAY(birthday) >= 22) OR (MONTH(birthday) = 1 AND DAY(birthday) <= 19) THEN '摩羯座'
      WHEN (MONTH(birthday) = 1 AND DAY(birthday) >= 20) OR (MONTH(birthday) = 2 AND DAY(birthday) <= 18) THEN '水瓶座'
      ELSE '双鱼座'
    END;
    RETURN sign_name;   这里提示出错!!!
END;   这里提示出错!!!

一共三处错误,想问问怎么修改?还有这个BEGIN-END这个结构相当于子查询吗?谢谢~

isdkz 发表于 2023-6-14 15:48:16

你遇到的问题是由于MySQL存储过程或函数语法的问题。首先,在MySQL中创建函数时,我们需要使用DELIMITER关键字更改语句结束符,这是因为在函数体中可能包含多条SQL语句,这些语句都是以分号(;)结束的,所以我们需要更改语句结束符,以便MySQL服务器能识别函数体结束的位置。

以下是修复错误后的代码:

DELIMITER //

CREATE FUNCTION show_sign(birthday DATE)
RETURNS VARCHAR(20)
BEGIN
    DECLARE sign_name VARCHAR(20);
    SET sign_name = CASE
      WHEN (MONTH(birthday) = 3 AND DAY(birthday) >= 21) OR (MONTH(birthday) = 4 AND DAY(birthday) <= 19) THEN '白羊座'
      WHEN (MONTH(birthday) = 4 AND DAY(birthday) >= 20) OR (MONTH(birthday) = 5 AND DAY(birthday) <= 20) THEN '金牛座'
      WHEN (MONTH(birthday) = 5 AND DAY(birthday) >= 21) OR (MONTH(birthday) = 6 AND DAY(birthday) <= 21) THEN '双子座'
      WHEN (MONTH(birthday) = 6 AND DAY(birthday) >= 22) OR (MONTH(birthday) = 7 AND DAY(birthday) <= 22) THEN '巨蟹座'
      WHEN (MONTH(birthday) = 7 AND DAY(birthday) >= 23) OR (MONTH(birthday) = 8 AND DAY(birthday) <= 22) THEN '狮子座'
      WHEN (MONTH(birthday) = 8 AND DAY(birthday) >= 23) OR (MONTH(birthday) = 9 AND DAY(birthday) <= 22) THEN '处女座'
      WHEN (MONTH(birthday) = 9 AND DAY(birthday) >= 23) OR (MONTH(birthday) = 10 AND DAY(birthday) <= 23) THEN '天秤座'
      WHEN (MONTH(birthday) = 10 AND DAY(birthday) >= 24) OR (MONTH(birthday) = 11 AND DAY(birthday) <= 22) THEN '天蝎座'
      WHEN (MONTH(birthday) = 11 AND DAY(birthday) >= 23) OR (MONTH(birthday) = 12 AND DAY(birthday) <= 21) THEN '射手座'
      WHEN (MONTH(birthday) = 12 AND DAY(birthday) >= 22) OR (MONTH(birthday) = 1 AND DAY(birthday) <= 19) THEN '摩羯座'
      WHEN (MONTH(birthday) = 1 AND DAY(birthday) >= 20) OR (MONTH(birthday) = 2 AND DAY(birthday) <= 18) THEN '水瓶座'
      ELSE '双鱼座'
    END;
    RETURN sign_name;
END//

DELIMITER ;


至于你的问题,BEGIN-END结构是否相当于子查询,答案是不相同的。BEGIN-END在MySQL中主要用于定义一个程序块,这个程序块中可以包含多条SQL语句,可以认为是一种控制流结构,用于执行复杂的逻辑处理。而子查询(Subquery)是嵌在其他SQL语句中的SELECT语句,用于返回数据用于外部查询的进一步处理。

黑脸艺术家 发表于 2023-6-14 15:54:38

本帖最后由 黑脸艺术家 于 2023-6-14 16:09 编辑

isdkz 发表于 2023-6-14 15:48
你遇到的问题是由于MySQL存储过程或函数语法的问题。首先,在MySQL中创建函数时,我们需要使用DELIMITER关 ...

好的非常感谢!请问你这部分代码开头与结尾处的两个DELIMITER是什么作用
且运行后出现错误:Error Code: 1418. This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

isdkz 发表于 2023-6-14 16:30:57

黑脸艺术家 发表于 2023-6-14 15:54
好的非常感谢!请问你这部分代码开头与结尾处的两个DELIMITER是什么作用
且运行后出现错误:Error Cod ...

在MySQL中,我们经常会使用分号(;)来标志一个SQL语句的结束。当我们需要写一个存储过程或者函数时,这个过程或函数内部可能包含多个SQL语句,每个语句都会用分号结尾。因此,我们需要告诉MySQL,整个过程或函数定义应当被视为一个单独的“语句”,而不是一系列的独立语句。为了做到这一点,我们可以用 DELIMITER 关键字暂时更改语句结束符,比如更改为"//”。

第一个 DELIMITER // 告诉MySQL,我们接下来的语句结束符将会是"//",而不是分号。然后,我们定义了存储过程,整个存储过程定义结束时,我们使用了"//"。接着,我们使用 DELIMITER ; 再次更改回语句结束符,使其恢复成分号。

至于你碰到的错误,是因为MySQL的服务器配置需要知道你创建的这个函数是否具有确定性,是否读取或者修改数据。你可以在 CREATE FUNCTION 后添加 DETERMINISTIC READS SQL DATA ACCESS 这样的关键字告诉MySQL你的函数的性质。

以下是一个例子:

DELIMITER //

CREATE FUNCTION show_sign(birthday DATE)
RETURNS VARCHAR(20) DETERMINISTIC READS SQL DATA ACCESS IN SQL LANGUAGE SQL
BEGIN
    DECLARE sign_name VARCHAR(20);
    SET sign_name = CASE
      ...
    END;
    RETURN sign_name;
END//

DELIMITER ;


这个例子告诉MySQL,这个函数是确定性的(即相同的输入总是返回相同的输出),并且只读取数据,不修改数据。

如果你不能修改函数,另一个可能的解决方案是更改服务器的配置,让它信任存储过程的创建者。这可以通过运行以下语句实现:

SET GLOBAL log_bin_trust_function_creators = 1;


但是这种方法的安全性较低,因为它可以允许创建者创建修改数据的函数。
页: [1]
查看完整版本: 在MySQL中输入提示三次错误??