如果我在 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 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
更新员工
你必须使用
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 //