MySQL表为空时插入数据遇1064语法错误,求正确写法
解决MySQL中IF NOT EXISTS插入数据的语法错误问题
这个问题我碰到过不少次——你写的IF NOT EXISTS控制结构,在MySQL的普通SQL执行上下文(比如直接在客户端、命令行执行单条语句)里是不被支持的,这种语法只能用在存储过程、函数或者触发器这类编程式的场景中,所以才会报1064语法错误。
下面给你两种可行的解决思路:
解决方案1:改用INSERT ... SELECT语法(推荐)
不需要用到IF语句,直接通过INSERT结合SELECT和NOT EXISTS来实现需求,把两个插入操作合并成一条语句,效率更高:
INSERT INTO `account_types` (`type`, `group`) SELECT '400', 'test' WHERE NOT EXISTS (SELECT 1 FROM `account_types`) UNION ALL SELECT '401', 'test2' WHERE NOT EXISTS (SELECT 1 FROM `account_types`);
原理说明:
- 当
account_types表为空时,两个SELECT语句的WHERE条件都会成立,返回对应的两行数据,最终插入到表中; - 如果表中已有数据,
WHERE NOT EXISTS条件不满足,SELECT不会返回任何数据,也就不会执行插入操作。
解决方案2:用存储过程包裹IF逻辑
如果你一定要保留IF NOT EXISTS的写法,就需要把这段逻辑放到存储过程里,因为存储过程支持MySQL的控制流语句:
-- 先修改语句分隔符,避免和存储过程里的分号冲突 DELIMITER // CREATE PROCEDURE InsertAccountTypesIfEmpty() BEGIN IF NOT EXISTS(SELECT 1 FROM `account_types`) THEN INSERT INTO `account_types` (`type`, `group`) VALUES ('400', 'test'); INSERT INTO `account_types` (`type`, `group`) VALUES ('401', 'test2'); END IF; END // -- 改回默认的分号分隔符 DELIMITER ; -- 调用存储过程执行逻辑 CALL InsertAccountTypesIfEmpty();
注意事项:
- 存储过程只需要创建一次,之后每次需要执行这个逻辑时,调用
CALL InsertAccountTypesIfEmpty();即可; - 如果你的MySQL用户没有创建存储过程的权限,需要先申请对应权限。
内容的提问来源于stack exchange,提问作者user9674353
相关产品推荐
相关产品推荐

