MySQL 存储函数无法使用 MODIFIES SQL DATA 进行编译

问题描述 投票:0回答:2

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

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

但是,如果我将

MODIFIES SQL DATA
更改为
READS SQL DATA
,该函数就可以正常编译。 MySQL手册说:

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
mysql mysql-workbench
2个回答
1
投票

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

编辑:

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

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

参见mysql解释,内容如下:

默认情况下,要接受 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

更新员工


0
投票

你必须使用

READS SQL DATA

严格来说,调用函数

DETERMINISTIC
并不准确,因为它的作用取决于函数参数以外的变量(取决于数据库中的内容)

DETERMINISTIC
函数类似于
Capitalize
函数,其中输出仅取决于输入参数(并且没有其他外部变量,例如查询时数据库中的内容)

DELIMITER //
drop function if exists Capitalize //
create function Capitalize( word varchar(200) )
returns varchar(200)
DETERMINISTIC
begin
return CONCAT( UCASE ( LEFT (word, 1) ), SUBSTRING( word, 2 ) );
END //
© www.soinside.com 2019 - 2024. All rights reserved.