You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MariaDB 10.3版本实现数据不存在即插入功能报错如何解决?

问题根因

  1. 1064语法报错原因:MariaDB 10.3及更低版本不支持无FROM子句的SELECT语句直接跟随WHERE条件,你需要查询固定常量并附加判断条件时,要使用内置虚拟表DUAL作为查询来源。
  2. 添加FROM bot_onet.Accuse后无报错但插入失败原因:此时SELECT的结果行数和accuse表的行数强绑定,若表为空则返回0行自然无法插入;若表有数据要么插入N条重复记录(N为表行数),要么NOT IN条件不生效时返回0行,不符合业务预期。
  3. 额外注意:NOT IN语法如果子查询返回NULL值,整体判断条件会变为未知,会直接导致插入逻辑失效,稳定性较差。

推荐解决方案(兼容所有MariaDB版本,性能最优)

通过唯一约束+INSERT IGNORE实现不存在则插入的逻辑,避免子查询带来的各种问题:

  1. 先给accuse表的去重标识字段lienFaceit添加唯一索引:
ALTER TABLE `bot_onet`.`accuse` ADD UNIQUE INDEX `uk_lienFaceit` (`lienFaceit`);
  1. 替换存储过程中的插入和ID取值逻辑即可:
CREATE DEFINER=`root`@`localhost` PROCEDURE `close_ticket`(IN idT INT,IN accuse VARCHAR(45),IN lienAccuse VARCHAR(60), IN lienG VARCHAR(60),IN jours INT,IN reason VARCHAR(250), IN isclosed BOOLEAN)
BEGIN
    -- 重复lienFaceit自动跳过插入,无报错
    INSERT IGNORE INTO bot_onet.accuse (`Pseudo`,`lienFaceit`) VALUES (accuse, lienAccuse);
    -- 加LIMIT 1避免多匹配行导致的取值错误
    SELECT `idAccuse` INTO @ID FROM bot_onet.accuse WHERE `lienFaceit` = lienAccuse LIMIT 1;
    INSERT INTO bot_onet.ticket_has_accuse (`Ticket_idTicket`,`Accuse_idAccuse`,`duree`,`timecode`,`unbaned`,`raison`) VALUES (idT,@ID,jours,unix_timestamp(),FALSE,reason) ;
    UPDATE bot_onet.ticket SET `Fermeture` = unix_timestamp(),`closed` = isclosed, `LienGame` = LienG WHERE idTicket = idT;
END

可选方案(无法添加唯一索引时使用)

如果你不能修改表结构加唯一索引,可以修正NOT IN写法,使用DUAL虚拟表并规避NULL值问题:

INSERT INTO bot_onet.accuse (`Pseudo`,`lienFaceit`) 
SELECT accuse, lienAccuse
FROM DUAL
-- 子查询加IS NOT NULL避免NULL导致NOT IN失效
WHERE lienAccuse NOT IN (SELECT `lienFaceit` FROM `bot_onet`.`accuse` WHERE `lienFaceit` IS NOT NULL);

内容的提问来源于stack exchange,提问作者C0casio45

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 04:27:04