MySQL8.0自定义函数

问题简介

[Err] 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)

[Err] 1418-此函数中没有声明DETERMINISTICNO SQLREADS SQL DATA,只用声明才会启用二进制日志记录(您可能想使用不太安全的log_bin_trust_function_creators变量)

解决办法

  1. 第一种办法,需要声明DETERMINISTICNO SQLREADS SQL DATA的一种

  2. 第二种办法,信任子程序的创建者,设置变量log_bin_trust_function_creators值为1

    -- 查看该参数,默认为0
    select @@log_bin_trust_function_creators;
    -- 设置为1
    set GLOBAL log_bin_trust_function_creators=1;
    

使用样例

  1. 函数声明NO SQL
-- mysql中创建一个自定义函数
delimiter $$
create function fun_addnum()
-- 注意是returns而不是return
returns int
NO SQL
begin 
 set @i=0;
add_num:LOOP
	set @i=@i+1;
	-- leave用于跳出循环
	if @i=10 then leave add_num;
	-- iterate跳过后面语句进入下一循环
	elseif mod(@i,2)=0 then iterate add_num;  
	end if;
	-- 结束循环
end loop add_num;
return @i;
end $$
delimiter ;

select fun_addnum();

  1. 函数声明DETERMINISTIC,表示该函数在每次为其参数调用相同值时都返回相同的结果值
delimiter $$
create function fun_hello(x int)
returns int
DETERMINISTIC
comment '这是注释' 
begin 
declare i int default 1; 
declare j int default 10; 
	case x
		when i then set x=i; 
		when j then set x=j;
		else set x=i+j;
	end CASE;
return x;
end $$
delimiter ;

select fun_hello(2);
  1. 设置变量log_bin_trust_function_creators的方式
-- 设置为1,此时才可以使用 CONTAINS SQL,MODIFIES SQL DATA
set GLOBAL log_bin_trust_function_creators=1;

delimiter $$
create function fun_temp()
returns int
 -- READS SQL DATA
 MODIFIES SQL DATA
begin 
declare cnt int default 0;
repeat 
	set cnt=cnt+1;
	until cnt=10 end repeat;
return cnt;
end $$
delimiter ;
  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL 8.0及以上版本并没有内置的序列函数,但可以通过自定义函数实现类似的功能。以下是一个简单的自定义函数实现序列的示例: 1. 创建自定义函数 ``` DELIMITER $$ CREATE FUNCTION seq_nextval(seq_name VARCHAR(50)) RETURNS BIGINT BEGIN DECLARE seq_val BIGINT DEFAULT 0; SET seq_val = (SELECT seq_val FROM sequence WHERE seq_name = seq_name FOR UPDATE); IF seq_val IS NULL THEN SET seq_val = 1; INSERT INTO sequence (seq_name, seq_val) VALUES (seq_name, seq_val); ELSE SET seq_val = seq_val + 1; UPDATE sequence SET seq_val = seq_val WHERE seq_name = seq_name; END IF; RETURN seq_val; END$$ DELIMITER ; ``` 上述代码中,我们创建了一个名为 seq_nextval 的自定义函数,它接受一个参数 seq_name,表示序列的名称。函数的作用是获取指定名称的序列的下一个值。 函数首先从名为 sequence 的表中获取指定名称的序列的当前值,如果该序列不存在,则将其初始化为1,并返回1。如果序列存在,则将其值加1,并更新 sequence 表中的值,最后返回更新后的值。 2. 创建序列表 在自定义函数中,我们用到了一个名为 sequence 的表,它用于存储所有序列的当前值。我们需要先创建该表: ``` CREATE TABLE sequence ( seq_name VARCHAR(50) PRIMARY KEY, seq_val BIGINT ); ``` 3. 使用自定义函数获取序列的下一个值 现在我们可以使用 seq_nextval 函数获取指定名称的序列的下一个值了: ``` SELECT seq_nextval('my_seq'); ``` 上述代码中,我们调用 seq_nextval 函数,并传入名称为 my_seq 的序列。函数会返回该序列的下一个值。 需要注意的是,由于自定义函数中用到了事务和行级锁,因此在高并发场景下可能会出现性能问题。如果需要生成大量的序列,建议使用自增主键或其他更高效的方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值