MySQL 存储函数不会使用 MODIFIES SQL DATA 编译

Posted

技术标签:

【中文标题】MySQL 存储函数不会使用 MODIFIES SQL DATA 编译【英文标题】:MySQL stored function won't compile with MODIFIES SQL DATA 【发布时间】:2020-03-27 21:15:19 【问题描述】:

如果我在 mysql 中编译下面的存储函数(使用 MySQL Workbench 8.0),我会收到消息:

错误 1418:此函数没有 DETERMINISTIC、NO SQL 或 READS 声明和二进制日志中的 SQL DATA 已启用...

但是,如果我将 MODIFIES SQL DATA 更改为 READS SQL DATA,则该函数编译得很好。 MySQL manual 说:

MODIFIES SQL DATA 表示例程包含的语句 可以写入数据(例如,INSERT 或 DELETE)。

那么为什么MODIFIES SQL DATA 不被接受?我了解这些特征“仅供参考”,但我仍想使用正确的特征。

CREATE FUNCTION DoSomething(employeeName VARCHAR(30)) RETURNS int(11)
    MODIFIES SQL DATA
BEGIN
   DECLARE income INT;

   SELECT Salary
   INTO income
   FROM Employee
   WHERE Name = employeeName;

   UPDATE Employee
   SET Salary = 300
   WHERE Name = employeeName;

   IF income < 5000 THEN
      RETURN 0;
   ELSE
      RETURN (income - 5000) * 0.1;
   END IF;
END

【问题讨论】:

【参考方案1】:

在 MySQL 8.0.19 和 Workbench 中使用 DETERMINISTIC 就足够了

编辑:

澄清一下,DETERMINISTIC、NO SQL 等函数选项 或 READS SQL DATA 不会做出任何决定,它只是表明您已经决定了它的安全性。 没有 SQL 或 READS SQL DATA 的函数清楚地告诉 MySQL 内部没有数据操作,它们是安全的。

通过使用 DETERMINISTIC 你告诉 mysql 运行这个函数是安全的,它确实在内部操作数据..

查看mysql explanation,内容如下:

默认情况下,要接受 CREATE FUNCTION 语句,至少 必须指定 DETERMINISTIC、NO SQL 或 READS SQL DATA 之一 明确的。

CREATE DEFINER=`root`@`localhost` FUNCTION `DoSomething`(employeeName VARCHAR(30)) RETURNS int
    DETERMINISTIC
BEGIN
   DECLARE income INT;

   SELECT Salary
   INTO income
   FROM Employee
   WHERE Name = employeeName;

   UPDATE Employee
   SET Salary = 300
   WHERE Name = employeeName;

   IF income < 5000 THEN
      RETURN 0;
   ELSE
      RETURN (income - 5000) * 0.1;
   END IF;
END

更新员工

【讨论】:

DETERMINISTIC 表示函数对相同的输入参数产生相同的结果。绝对不是这种情况,因为表值可以更改。但是,使用 NOT DETERMINISTIC 时,MySQL Workbench 无法编译。 好吧,我应该写更多的信息。函数只返回值,使用 DETERMINSTIC 向 mysql 表明您的函数是安全,出于安全原因,您可能无法在函数中使用某些东西,例如语句。因此,如果您希望在您的功能中获得最高更新员工,请按照我写的那样将其放在 DETERMINISTIC 中。

以上是关于MySQL 存储函数不会使用 MODIFIES SQL DATA 编译的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 说:#1336 - 存储函数或触发器中不允许使用动态 SQL

MySql存储过程与函数

mysql 存储过程与存储函数

MySQl之TCL(数据事务语言)

MySQL进阶实战2,那些年学过的事务

mysql创建函数或者存储过程,遇到语法报错