Ubuntu24.04下MariaDB10.6.22自定义函数无法用于生成列求助
问题解决:自定义函数用于MariaDB生成列的报错处理
问题原因
MariaDB的生成列对所用函数有严格限制:即使函数标记为DETERMINISTIC,如果未明确声明符合要求的SQL数据访问特性,或版本对自定义函数支持生成列的限制,就会触发ERROR 1901。你的cmm_unaccent函数仅做字符串替换,无表数据访问,但缺少关键特性声明。
解决方案
方案一:修改函数以适配生成列要求
为函数添加NO SQL特性(明确函数不访问任何SQL数据),修改后的函数代码如下:
delimiter $$ create or replace function cmm_unaccent(param_textvalue TEXT) returns TEXT DETERMINISTIC NO SQL begin DECLARE var_textvalue TEXT; DECLARE var_withaccents TEXT; DECLARE var_withoutaccents TEXT; DECLARE var_count INT; set var_textvalue = param_textvalue; -- 替换重音字符 set var_withaccents = 'ŠšŽžÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝŸÞàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿþƒ'; set var_withoutaccents = 'SsZzAAAAAAACEEEEIIIINOOOOOOUUUUYYBaaaaaaaceeeeiiiinoooooouuuuyybf'; set var_count = length(var_withaccents); while var_count > 0 do set var_textvalue = replace(var_textvalue, substring(var_withaccents, var_count, 1), substring(var_withoutaccents, var_count, 1)); set var_count = var_count - 1; end while; return var_textvalue; end$$ delimiter ;
修改完成后,重新执行最初的CREATE TABLE语句即可生成带自动无重音列的表。
方案二:用触发器替代生成列(更兼容)
如果修改函数后仍无法使用生成列,可通过触发器实现自动填充无重音列:
- 创建基础表(不含生成列)
create table testttnbg( idname bigint not null auto_increment, name text, afteryear integer default 0, birthyear text default null, gent text default null, needyob integer default 0, plainname text, primary key(idname) );
- 创建插入触发器
delimiter $$ create trigger trg_testttnbg_insert before insert on testttnbg for each row begin set new.plainname = cmm_unaccent(new.name); end$$ delimiter ;
- 创建更新触发器
delimiter $$ create trigger trg_testttnbg_update before update on testttnbg for each row begin if new.name <> old.name then set new.plainname = cmm_unaccent(new.name); end if; end$$ delimiter ;
后续插入或更新name字段时,plainname会自动同步为无重音版本,效果与生成列一致。
内容的提问来源于stack exchange,提问作者user3448254
相关产品推荐
相关产品推荐

