鱼C论坛

 找回密码
 立即注册
查看: 568|回复: 3

[已解决]在MySQL中输入提示三次错误??

[复制链接]
发表于 2023-6-14 15:44:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目是:创建一个函数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这个结构相当于子查询吗?谢谢~
最佳答案
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语句,用于返回数据用于外部查询的进一步处理。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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语句,用于返回数据用于外部查询的进一步处理。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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;

但是这种方法的安全性较低,因为它可以允许创建者创建修改数据的函数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 19:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表