当前位置:首页 > 技术分享

mysql批量更新避免触发唯一索引

admin1小时前技术分享2

方案 1【不改索引,批量禁用 SQL 写法

不改动索引结构,那就需要修改时保证唯一索引组合不冲突。 思路:冻结时,给 name 加特殊标记(例如后缀_disabled_学生id),保证唯一索引字段不会重复。 缺点:原 name 被篡改,后续恢复要把名字还原,适合临时方案。

批量禁用 SQL 示例(批量更新 student_id in (...)):

UPDATE my_student
SET 
    status = 0,
    name = CONCAT(name, '_disabled_', student_id), -- 追加id保证唯一
    update_time = UNIX_TIMESTAMP()
WHERE student_id IN (1001,1002,1003);

恢复启用的时候,需要把 name 再去掉后缀还原:

UPDATE my_student
SET status = 1, name = SUBSTRING_INDEX(name, '_disabled_',1), update_time=UNIX_TIMESTAMP()
WHERE student_id IN (1001,1002,1003);


方案 2 存储过程(按student_id循环

思路:循环逐个更新学生 ID,用异常捕获

  • 尝试只更新 status + update_time

  • 如果捕获唯一索引冲突异常 → 再执行带 name 拼接的更新

优点:业务逻辑干净,大部分学生只改状态;只有冲突的那几条才修改 name 字段。 缺点:需要创建存储过程,批量量大的时候循环会慢一点。

DELIMITER //
CREATE PROCEDURE batch_disable_student(IN ids VARCHAR(1000))
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE v_student_id INT;
    DECLARE CONTINUE HANDLER FOR 1062 -- 唯一索引冲突错误码
    BEGIN
        -- 冲突时:拼接name后缀再更新
        UPDATE my_student
        SET status = 0,
            name = CONCAT(name, '_disabled_', v_student_id),
            update_time = UNIX_TIMESTAMP()
        WHERE student_id = v_student_id;
    END;

    -- 拆分ids字符串,循环处理每个student_id
    WHILE i <= LENGTH(ids) DO
        SET v_student_id = SUBSTRING_INDEX(SUBSTRING_INDEX(ids, ',', i), ',', -1);
        -- 先尝试只更新状态
        UPDATE my_student
        SET status = 0, update_time = UNIX_TIMESTAMP()
        WHERE student_id = v_student_id;
        SET i = i + 1;
    END WHILE;
END //
DELIMITER ;

调用示例:

CALL batch_disable_student('1001,1002,1003');

⚠️ 注意:字符串拆分方式简单,ID 数量多建议改用临时表方式,避免字符串长度限制。

存储过程(按 class_id 循环)

DELIMITER //
CREATE PROCEDURE batch_disable_student_by_class(IN class_ids VARCHAR(1000))
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE v_class_id INT;
    DECLARE v_student_id INT;
    -- 唯一索引冲突捕获句柄
    DECLARE CONTINUE HANDLER FOR 1062
    BEGIN
        -- 冲突:修改姓名+标记
        UPDATE my_student
        SET status = 0,
            name = CONCAT(name, '_disabled_', v_student_id),
            update_time = UNIX_TIMESTAMP()
        WHERE student_id = v_student_id;
    END;

    -- 循环拆分 class_ids
    WHILE i <= LENGTH(class_ids) DO
        SET v_class_id = SUBSTRING_INDEX(SUBSTRING_INDEX(class_ids, ',', i), ',', -1);
        
        -- 游标遍历当前班级下待禁用学生(这里自行加WHERE条件,示例:status=1正常学生)
        BEGIN
            DECLARE done INT DEFAULT 0;
            DECLARE cur CURSOR FOR 
                SELECT student_id FROM my_student 
                WHERE class_id = v_class_id AND status = 1;
            DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
            
            OPEN cur;
            FETCH cur INTO v_student_id;
            WHILE done = 0 DO
                -- 优先尝试:只改状态,不改姓名
                UPDATE my_student
                SET status = 0, update_time = UNIX_TIMESTAMP()
                WHERE student_id = v_student_id;
                
                FETCH cur INTO v_student_id;
            END WHILE;
            CLOSE cur;
        END;

        SET i = i + 1;
    END WHILE;
END //
DELIMITER ;

调用示例

禁用 class_id=10,20,30 下面所有正常状态学生

CALL batch_disable_student_by_class('10,20,30');


扫描二维码推送至手机访问。

版权声明:本文由小刚刚技术博客发布,如需转载请注明出处。

本文链接:https://blog.bitefu.net/post/763.html

标签: mysql
分享给朋友:

“mysql批量更新避免触发唯一索引” 的相关文章

php-cgi占用太多cpu资源而导致服务器响应过慢 利用进程和Linux的proc 定位耗资源文件

php-cgi占用太多cpu资源而导致服务器响应过慢 利用进程和Linux的proc 定位耗资源文件

在此环境下,一般php-cgi运行是非常稳定的,但也遇到过php-cgi占用太多cpu资源而导致服务器响应过慢,我所遇到的php-cgi进程占用cpu资源过多的原因有: 1. 一些php的扩展与php版本兼容存在问题,实践证明 e…

WPS表格办公—取消科学计数法显示

WPS表格办公—取消科学计数法显示

我们在利用WPS表格与Excel表格进行日常办公时,经常需要制作各种各样的表格,当我们在表格当中输入长数据的时候,表格经常会自动显示为科学计数法,很多人都看不懂科学计数法的意思,那么,我们如何在输入长数字的时候避免显示为科学计数法呢,今天我…

解决 SVN Skipped 'xxx' -- Node remains in conflict

更新命令:svn up提示代码:意思就是说 ,这个文件冲突了,你要解决下Updating '.': Skipped 'data/config.php' -- …

超高性比的斐讯盒子T1,刷第三方YYF固件机教程超级详细版

超高性比的斐讯盒子T1,刷第三方YYF固件机教程超级详细版

家里面买了斐讯盒子T1,必不可少的就是刷机,刷机一直爽,一直刷机一直爽,这样的快乐一般人体会不到。原来斐讯盒子N1,T1,还有斐讯K2P路由器也变成了性价比超高的东东,而且众多大神也带来了超多可玩性非常高的固件和破解。楼主今天扒到了相关超高…

遭遇国外ip抓取或攻击怎么办一招解决禁止海外IP访问

遭遇国外ip抓取或攻击怎么办一招解决禁止海外IP访问

究发现很多网站被攻击都是来自海外的肉鸡,所以禁掉海外IP访问网站也是不错的防护手段,而且国内网站几乎很少有国外用户访问,称之为大局域网也不为过。今天主机吧来教大家如何利用域名解析禁止掉海外IP访问网站。绝大多数域名解析服务商都是提供电信联通…

Nginx服务崩溃自动重启脚本(监控进程服务并自动重启进程服务)脚本

有一台服务器运行着Ngin最近突然有一次崩溃,导致使用方当天无法访问网页端,然后我不得不登录服务器,检查各项服务,发现nginx崩溃了,于是重启Nginx,问题解决。后来为了防止Nginx再发生这种情况给运维带来的运维成本,于是写了一个脚本…

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。