MariaDB 10插入空字符串报错,触发器无效求解决方案
问题与解决建议
问题详情
现有一张包含float类型列的test表,列允许为NULL且默认值为NULL,建表语句如下:
CREATE TABLE `test` ( `test` float DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
在MySQL 5中执行INSERT INTO test VALUES ('')可正常运行,但在MariaDB 10中执行该语句会抛出错误:
#1366 - Incorrect double value: '' for column
nico.test.testat row 1
尝试创建BEFORE INSERT触发器,意图将空值替换为NULL或0,但以下两个触发器均未生效,错误依旧:
测试触发器1(替换为NULL):
DELIMITER // CREATE TRIGGER test_vide BEFORE INSERT ON test FOR EACH ROW BEGIN IF NEW.test='' THEN SET NEW.test=NULL; END IF; END; // DELIMITER ;
测试触发器2(替换为0):
DELIMITER // CREATE TRIGGER test_vide BEFORE INSERT ON test FOR EACH ROW BEGIN IF NEW.test='' THEN SET NEW.test='0'; END IF; END; // DELIMITER ;
原因分析
触发器失效的核心原因是MariaDB 10默认开启了严格SQL模式(STRICT_TRANS_TABLES):
- 在严格模式下,MariaDB会在触发器执行之前,先对插入值做类型校验。空字符串
''无法转换为float类型,直接触发1366错误,导致触发器根本没有执行的机会。 - MySQL 5默认未开启严格模式,会自动将空字符串隐式转换为0,因此不会报错。
可行解决方法
1. 调整SQL_MODE,关闭严格类型校验
先查看当前SQL_MODE配置:
SELECT @@SQL_MODE;
临时修改(重启服务后失效):
SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION';
永久修改需编辑配置文件(Linux为my.cnf,Windows为my.ini),添加或修改:
sql_mode = NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION
修改后重启MariaDB服务即可生效。
2. 插入时显式处理空值
在INSERT语句中直接对空字符串做转换,避免类型校验报错:
- 转NULL:
INSERT INTO test VALUES (NULLIF('', ''));
- 转0:
INSERT INTO test VALUES (IF('', '', 0));
或者使用CASE语句:
INSERT INTO test VALUES (CASE WHEN '' = '' THEN NULL ELSE '' END);
3. 改用存储过程封装插入逻辑
如果需要批量处理或统一逻辑,可以创建存储过程来处理插入值的转换:
DELIMITER // CREATE PROCEDURE insert_test(IN val VARCHAR(255)) BEGIN DECLARE insert_val FLOAT; IF val = '' THEN SET insert_val = NULL; -- 或设为0 ELSE SET insert_val = CAST(val AS FLOAT); END IF; INSERT INTO test VALUES (insert_val); END // DELIMITER ;
调用存储过程插入:
CALL insert_test('');
4. 应用层提前处理
在应用代码中,将空字符串转换为NULL或0后再执行插入,从源头避免类型转换问题。
内容的提问来源于stack exchange,提问作者Nico Angenon
相关产品推荐
相关产品推荐

