数据库 MySQL 的创建函数

Posted

技术标签:

【中文标题】数据库 MySQL 的创建函数【英文标题】:Creation function for database MySQL 【发布时间】:2022-01-16 20:33:37 【问题描述】:

我有一个数据库“短途旅行”,其中包含有关客户、公共汽车、司机、账单和短途旅行的信息。我需要创建一个函数来计算一个客户指定月份的付款。我ve already created it. Also ive 创建了一个为所有客户调用该函数的过程。但是 mysql Workbench 告诉我有一个错误。帮我解决它

USE excursions_test;
DELIMITER $$
CREATE FUNCTION  sum_bill(excursion_id INT, for_begin DATE, for_end DATE) RETURNS INT
DETERMINISTIC
    BEGIN
       SELECT excStart = excursion.start_date, excEnd = excursion.end_date, excPrice =( excursion.excursion_duration*excursion.number_of_tourists*bus_model.fuel_for_km*excursion.distance)*1.5,
        IF(excStart < for_begin OR excEnd > for_end, 0, 
        IF(excStart <= for_begin OR excEnd >= for_end AND excEnd <= for_end, DATEDIFF(for_begin, excEnd)*excPrice/30,
        IF(excStart >= for_begin AND excEnd >= for_begin AND excEnd <= for_end, DATEDIFF(excStart, excEnd)*excPrice/30,
        IF(excStart >= for_begin AND excEnd >= for_end, DATEDIFF(excStart, for_end)*excPrice/30,
        IF(excStart <= for_begin AND excEnd >= for_end, DATEDIFF(for_begin, for_end)*excPrice/30, 0)))))
        FROM excursion JOIN bus_model ON excursion.bus_model_id = bus_model.bus_model_id
        WHERE excursion.excursion_id = excursion_id;
        RETURN 0;
    END $$
    DELIMITER ;

DELIMITER $$
CREATE PROCEDURE bill_creator(for_begin DATE, for_end DATE)
BEGIN
    INSERT INTO bill(excursion_id, start_date, end_date, amount)
    SELECT excursion.excursion_id, for_begin, for_end, dbo.sum_bill(dbo.excursion.excursion_id, for_begin, for_end)
    FROM excursion
    WHERE (excursion.start_date >= for_begin AND excursion.end_date <= for_end)
        OR (excursion.end_date >= for_begin AND excursion.end_date <= for_end)
        OR (excursion.start_date<= for_begin AND excursion.end_date>= for_begin);
END $$
DELIMITER ;

CALL bill_creator ('2021-10-01', '2021-10-31')

错误:不允许从函数返回结果集

【问题讨论】:

你确定这是mysql吗?使用dbo表示sql_server.. 函数的意义何在?结果总是返回 0。它有一个 select 语句,它只返回一个结果集,根据错误消息,这是不允许的。 如果你是从 ms sql server 迁移代码到 mysql,那么你需要将所有代码转换为 mysql 语法,而不仅仅是部分代码! 【参考方案1】:

您正在返回具有多列但函数的返回类型为 int 的单行结果集。

我还没有测试以下内容,因此您可能需要对其进行调整,但如果您更换该部分,错误应该会得到修复

   SELECT excStart = excursion.start_date, excEnd = excursion.end_date, excPrice =( excursion.excursion_duration*excursion.number_of_tourists*bus_model.fuel_for_km*excursion.distance)*1.5,
    IF(excStart < for_begin OR excEnd > for_end, 0, 
    IF(excStart <= for_begin OR excEnd >= for_end AND excEnd <= for_end, DATEDIFF(for_begin, excEnd)*excPrice/30,
    IF(excStart >= for_begin AND excEnd >= for_begin AND excEnd <= for_end, DATEDIFF(excStart, excEnd)*excPrice/30,
    IF(excStart >= for_begin AND excEnd >= for_end, DATEDIFF(excStart, for_end)*excPrice/30,
    IF(excStart <= for_begin AND excEnd >= for_end, DATEDIFF(for_begin, for_end)*excPrice/30, 0)))))
    FROM excursion JOIN bus_model ON excursion.bus_model_id = bus_model.bus_model_id
    WHERE excursion.excursion_id = excursion_id;
    RETURN 0;

SELECT excStart = excursion.start_date, excEnd = excursion.end_date, excPrice =( excursion.excursion_duration*excursion.number_of_tourists*bus_model.fuel_for_km*excursion.distance)*1.5;
    FROM excursion JOIN bus_model ON excursion.bus_model_id = bus_model.bus_model_id
    WHERE excursion.excursion_id = excursion_id;

IF(excStart < for_begin OR excEnd > for_end)
BEGIN
    RETURN 0;
END;

IF(excStart <= for_begin OR excEnd >= for_end AND excEnd <= for_end)
BEGIN
    RETURN  DATEDIFF(for_begin, excEnd)*excPrice/30;
END;

IF(excStart >= for_begin AND excEnd >= for_begin AND excEnd <= for_end)
BEGIN
    RETURN  DATEDIFF(excStart, excEnd)*excPrice/30;
END;

IF(excStart >= for_begin AND excEnd >= for_end)
BEGIN
    RETURN  DATEDIFF(excStart, for_end)*excPrice/30;
END;

IF(excStart <= for_begin AND excEnd >= for_end)
BEGIN
    RETURN  DATEDIFF(for_begin, for_end)*excPrice/30, 0;
END;

RETURN 0;

【讨论】:

1) 您还没有声明任何变量。 2)select variable_name = expression ...是ms sql语法,不是mysql。 Mysql 需要选择进入。请参阅 P.Salmon 在询问 OP 使用什么数据库产品的问题下的评论。 1) 变量已经在我建议替换的代码部分之前声明。 2)我看到了那条评论,并假设它实际上是基于语法和命名的 sql server。 1) 除了存储过程和函数中的参数外,没有在任何地方声明变量。 2)如果您认为它是 ms sql 而不是 mysql,那么您应该在答案中明确说明并将所有语法转换为 ms sql 服务器(分隔符、函数声明、在变量名中使用 @ 等)。但是,错误消息和声明存储过程和函数的语法以及问题标记表明使用了 mysql。

以上是关于数据库 MySQL 的创建函数的主要内容,如果未能解决你的问题,请参考以下文章

数据库 MySQL 的创建函数

mysql数据库创建函数过程

Mysql 创建自定义函数

mysql为四个表创建储存过程或者储存函数

为啥mysql创建存储函数,会是这样报错

Java学习总结(十八)——MySQL数据库MySQL数据库中的视图,函数,存储过程中常见循环