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

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

admin1个月前 (09-10)技术分享95

方案 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高效检测远程图片是否存在

php高效检测远程图片是否存在function img_exits($url){     $ch = curl_init();    &…

input search更改默认删除按钮的样式

改input输入框search属性下输入文字之后会在输入框最后出现一个默认样式的X不过这个样式不太好看想自定义怎么办呢方法一input[type="search"]::-webkit-search-cancel-butt…

贾氏鸣天鼓健耳养肾操

贾氏鸣天鼓健耳养肾操

《贾氏鸣天鼓健耳养肾操》鸣天鼓是健耳强肾治耳病的古法,贾氏越云自创的鸣天鼓健耳养肾操是在古法的基础上创建。顺序:1静坐挺胸。2双手放心脏位置的胸口,左手掌盖住右手掌。3闭目静心,深呼吸19下。4双手相互搓揉,让手掌发热。5用发热的双手手掌严…

微软Windows 10升级密钥(例如家庭版升级为企业版) 不能用于激活系统

微软Windows 10升级密钥(例如家庭版升级为企业版) 不能用于激活系统

下面的密钥,是微软官方提供的,仅能用于Windows10系统版本的升级,比如从家庭版升级为专业版、专业版升级为企业版等。升级密钥不能用于激活系统,激活需要KMS或者数字权利,由于涉及到版权问题,在此不宜分享,请大家自行查找激活相关的内容。准…

PIP 更换国内安装源linux/windows

pip国内的一些镜像  阿里云 http://mirrors.aliyun.com/pypi/simple/   中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/   豆瓣(…

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

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

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

发表评论

访客

看不清,换一张

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