数据库SQL小技巧大揭秘:IGNORE选项让你的数据处理更从容

news/2025/3/3 20:38:46/

点击上方蓝字关注我

23d29c03b006055a0457f05100da3bdf.jpeg

    在 MySQL 中,IGNORE 是一种在插入或更新数据时处理冲突的选项。具体来说,在 INSERT | UPDATE 语句中,IGNORE 的作用是在插入或更新数据时忽略特定的错误,而不导致整个操作失败。另外,IGNORE 选项还可以在非空约束、写入的字段内容超过字段长度时进行截断处理等,下面是几个具体的例子。

1.  主键或唯一键冲突

1.1 初始化测试表并初始化数据

mysql> create table  test1(id int not null primary key,
card_no varchar(10)  not null,
name varchar(20) not null, 
c1 varchar(2) ,
unique key uq_card_no(card_no)
);
Query OK, 0 rows affected (0.05 sec)mysql> insert into test1(id,card_no,name,c1) 
values(1,'1000000000','abc','a')
Query OK, 1 row affected (0.01 sec)mysql> select * from test1;
+----+------------+------+------+
| id | card_no    | name | c1   |
+----+------------+------+------+
|  1 | 1000000000 | abc  | a    |
+----+------------+------+------+
1 row in set (0.00 sec)

bdefac254058ba814983b30145e48f5e.jpeg

1.2 主键冲突

插入一个表中已存在的主键数据时,如果不添加ignore,则会报主键冲突

mysql>  insert into test1(id,card_no,name,c1) values(1,'1000000001','abc','a');
ERROR 1062 (23000): Duplicate entry '1' for key 'test1.PRIMARY'

加上ignore选项后,结果如下:

mysql> select * from test1;
+----+------------+------+------+
| id | card_no    | name | c1   |
+----+------------+------+------+
|  1 | 1000000000 | abc  | a    |
+----+------------+------+------+
1 row in set (0.00 sec)mysql>  insert ignore into test1(id,card_no,name,c1) values(1,'1000000001','abc','a'),-> (2,'1000000001','ttt','b');
Query OK, 1 row affected, 1 warning (0.01 sec)
Records: 2  Duplicates: 1  Warnings: 1mysql> show warnings;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1062 | Duplicate entry '1' for key 'test1.PRIMARY' |
+---------+------+---------------------------------------------+
1 row in set (0.00 sec)mysql> select * from test1;
+----+------------+------+------+
| id | card_no    | name | c1   |
+----+------------+------+------+
|  1 | 1000000000 | abc  | a    |
|  2 | 1000000001 | ttt  | b    |
+----+------------+------+------+
2 rows in set (0.00 sec)

c22404774e11290c712ee9de47f30bd8.jpeg

可以看到,有1条记录冲突,但是进行了warning提示,然后继续进行其他无冲突项的处理。

如果需查看warning信息,可以使用 show warnings 命令查看。

1.3  唯一键冲突

继续以上的表,先正常方式插入一条唯一键已存在的记录

mysql> select * from test1;
+----+------------+------+------+
| id | card_no    | name | c1   |
+----+------------+------+------+
|  1 | 1000000000 | abc  | a    |
|  2 | 1000000001 | ttt  | b    |
+----+------------+------+------+
2 rows in set (0.00 sec)mysql> insert  into test1(id,card_no,name,c1) values (4,'1000000000','ccccc','a');
ERROR 1062 (23000): Duplicate entry '1000000000' for key 'test1.uq_card_no'
mysql> select * from test1;
+----+------------+------+------+
| id | card_no    | name | c1   |
+----+------------+------+------+
|  1 | 1000000000 | abc  | a    |
|  2 | 1000000001 | ttt  | b    |
+----+------------+------+------+
2 rows in set (0.00 sec)

可见,因为报错,数据未插入。

a9aaea0189b5c570abd20b9f258d9027.jpeg

下面通过添加ignore批量插入数据

mysql> select * from test1;
+----+------------+------+------+
| id | card_no    | name | c1   |
+----+------------+------+------+
|  1 | 1000000000 | abc  | a    |
|  2 | 1000000001 | ttt  | b    |
+----+------------+------+------+
2 rows in set (0.00 sec)mysql> insert ignore into test1(id,card_no,name,c1) values-> (4,'1000000000','ccccc','a'),-> (5,'1000000003','ccccabc','a');
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 2  Duplicates: 1  Warnings: 1mysql> show warnings;
+---------+------+---------------------------------------------------------+
| Level   | Code | Message                                                 |
+---------+------+---------------------------------------------------------+
| Warning | 1062 | Duplicate entry '1000000000' for key 'test1.uq_card_no' |
+---------+------+---------------------------------------------------------+
1 row in set (0.00 sec)mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  2 | 1000000001 | ttt     | b    |
|  5 | 1000000003 | ccccabc | a    |
+----+------------+---------+------+
3 rows in set (0.00 sec)mysql>

658a8ec77810535fa62b1cfe9b35ab8d.jpeg

可见,和主键冲突类似,有冲突的数据将会忽略告警而继续进行后续操作。

1.4 update操作

除了insert可以搭配ignore选项,update也可以添加ignore选项,例如:

更新主键:

mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  2 | 1000000001 | ttt     | b    |
|  5 | 1000000003 | ccccabc | a    |
+----+------------+---------+------+
3 rows in set (0.00 sec)mysql> update test1 set id = id +1;
ERROR 1062 (23000): Duplicate entry '2' for key 'test1.PRIMARY'
mysql> update ignore test1 set id = id +1;
Query OK, 2 rows affected, 1 warning (0.01 sec)
Rows matched: 3  Changed: 2  Warnings: 1mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000001 | ttt     | b    |
|  6 | 1000000003 | ccccabc | a    |
+----+------------+---------+------+
3 rows in set (0.00 sec)mysql>

47a9fd130aba290d566e92be7f3a8af7.jpeg

更新唯一键:

mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000001 | ttt     | b    |
|  6 | 1000000003 | ccccabc | a    |
+----+------------+---------+------+
3 rows in set (0.00 sec)mysql> show warnings;
Empty set (0.00 sec)mysql> update test1 set card_no=card_no +1;
ERROR 1062 (23000): Duplicate entry '1000000001' for key 'test1.uq_card_no'
mysql> update ignore test1 set card_no=card_no +1;
Query OK, 2 rows affected, 1 warning (0.02 sec)
Rows matched: 3  Changed: 2  Warnings: 1mysql> show warnings;
+---------+------+---------------------------------------------------------+
| Level   | Code | Message                                                 |
+---------+------+---------------------------------------------------------+
| Warning | 1062 | Duplicate entry '1000000001' for key 'test1.uq_card_no' |
+---------+------+---------------------------------------------------------+
1 row in set (0.00 sec)mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
+----+------------+---------+------+
3 rows in set (0.00 sec)mysql>

f73b0f5886b786cddf6b701ff1496771.jpeg

2.  忽略非空约束

2.1 列出字段赋值为null时

当列出需赋值的字段,但是对其中的非空字段赋值为null时,结果如下:

mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
+----+------------+---------+------+
3 rows in set (0.00 sec)mysql> insert into test1(id,card_no,name,c1) values-> (7,'1000000005',null,'aa');
ERROR 1048 (23000): Column 'name' cannot be null
mysql> insert ignore  into test1(id,card_no,name,c1) values (7,'1000000005',null,'aa');
Query OK, 1 row affected, 1 warning (0.01 sec)mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
+----+------------+---------+------+
4 rows in set (0.00 sec)

378190da20d735b8fd38d99f26942411.jpeg

结果为:会插入一个空字符串在表中而不会像正常SQL那样因为非空约束而失败。

有人疑惑,上面是空字符串么,验证结果如下:

mysql> select * from test1 where name='';
+----+------------+------+------+
| id | card_no    | name | c1   |
+----+------------+------+------+
|  7 | 1000000005 |      | aa   |
+----+------------+------+------+
1 row in set (0.00 sec)mysql> select * from test1 where name is null;
Empty set (0.00 sec)

6f59f383f827e10a2d6367b25dbd3334.jpeg

2.2  未列出字符串类型字段名

当赋值时未在字段列表中加入有非空约束的字符串类型的字段时,情况如下:

mysql> insert   into test1(id,name,c1) values (8,'aaa','aa');
ERROR 1364 (HY000): Field 'card_no' doesn't have a default value
mysql> insert  ignore  into test1(id,name,c1) values (8,'aaa','aa');
Query OK, 1 row affected, 1 warning (0.01 sec)mysql> show warnings;
+---------+------+----------------------------------------------+
| Level   | Code | Message                                      |
+---------+------+----------------------------------------------+
| Warning | 1364 | Field 'card_no' doesn't have a default value |
+---------+------+----------------------------------------------+
1 row in set (0.00 sec)mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
+----+------------+---------+------+
5 rows in set (0.01 sec)

baa5f39b5f1e173dd6ada997bc1fcdd2.jpeg

可见,字段未列出时,也可以插入成功,也是将其插入一个空字符串

2.3 未列整型字段时

当赋值时未在字段列表中加入有非空约束的整型类型的字段时,情况如下:

mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
+----+------------+---------+------+
5 rows in set (0.01 sec)mysql> insert  ignore  into test1(card_no,name,c1) values ('1000000006','bbb','aa');
Query OK, 1 row affected, 1 warning (0.00 sec)mysql> show warnings;
+---------+------+-----------------------------------------+
| Level   | Code | Message                                 |
+---------+------+-----------------------------------------+
| Warning | 1364 | Field 'id' doesn't have a default value |
+---------+------+-----------------------------------------+
1 row in set (0.00 sec)mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  0 | 1000000006 | bbb     | aa   |
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
+----+------------+---------+------+
6 rows in set (0.00 sec)mysql>

f391c616bd4d39e849c3d10428d34a92.jpeg

结果:此时插入了0 (整型的默认值)。

3.  字段超长

依旧进行在上述的测试表上进行测试

3.1  字符串超长

当字符串类型超长时,正常结果如下:

mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  0 | 1000000006 | bbb     | aa   |
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
+----+------------+---------+------+
6 rows in set (0.00 sec)mysql> insert into test1(id,card_no,name,c1) values(9,'1000000001','abc','a12345');
ERROR 1406 (22001): Data too long for column 'c1' at row 1
mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  0 | 1000000006 | bbb     | aa   |
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
+----+------------+---------+------+
6 rows in set (0.00 sec)

结果:数据会因超长而未插入。

而使用ignore选项后,结果如下:

mysql> insert ignore into test1(id,card_no,name,c1) values(9,'1000000001','abc','a12345');
Query OK, 1 row affected, 1 warning (0.01 sec)mysql> show warnings;
+---------+------+-----------------------------------------+
| Level   | Code | Message                                 |
+---------+------+-----------------------------------------+
| Warning | 1265 | Data truncated for column 'c1' at row 1 |
+---------+------+-----------------------------------------+
1 row in set (0.00 sec)mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  0 | 1000000006 | bbb     | aa   |
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
|  9 | 1000000001 | abc     | a1   |
+----+------------+---------+------+
7 rows in set (0.00 sec)mysql> desc test1;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int         | NO   | PRI | NULL    |       |
| card_no | varchar(10) | NO   | UNI | NULL    |       |
| name    | varchar(20) | NO   |     | NULL    |       |
| c1      | varchar(2)  | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)mysql>

db85b79df9f47740c8b77728acd20438.jpeg

结果:数据以截断的方式插入成功了。

3.2  整型数据超长

当普通方式插入一个超过int类型最大值的数据时,会直接因数据超过范围而报错。例如:

mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  0 | 1000000006 | bbb     | aa   |
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
|  9 | 1000000001 | abc     | a1   |
+----+------------+---------+------+
7 rows in set (0.00 sec)mysql> insert  into test1(id,card_no,name,c1) values(999999999999999999999,'1000000003','abc','a2');
ERROR 1264 (22003): Out of range value for column 'id' at row 1
mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  0 | 1000000006 | bbb     | aa   |
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
|  9 | 1000000001 | abc     | a1   |
+----+------------+---------+------+
7 rows in set (0.00 sec)

aad5f2788408d5f4453170ad241a012e.jpeg

而使用ignore选项后,可以插入数据,例如:

mysql> select * from test1;
+----+------------+---------+------+
| id | card_no    | name    | c1   |
+----+------------+---------+------+
|  0 | 1000000006 | bbb     | aa   |
|  1 | 1000000000 | abc     | a    |
|  3 | 1000000002 | ttt     | b    |
|  6 | 1000000004 | ccccabc | a    |
|  7 | 1000000005 |         | aa   |
|  8 |            | aaa     | aa   |
|  9 | 1000000001 | abc     | a1   |
+----+------------+---------+------+
7 rows in set (0.00 sec)mysql> insert ignore  into test1(id,card_no,name,c1) values(999999999999999999999,'1000000003','abc','a2');
Query OK, 1 row affected, 2 warnings (0.01 sec)mysql> show warnings;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'id' at row 1 |
| Warning | 1264 | Out of range value for column 'id' at row 1 |
+---------+------+---------------------------------------------+
2 rows in set (0.00 sec)mysql> select * from test1;
+------------+------------+---------+------+
| id         | card_no    | name    | c1   |
+------------+------------+---------+------+
|          0 | 1000000006 | bbb     | aa   |
|          1 | 1000000000 | abc     | a    |
|          3 | 1000000002 | ttt     | b    |
|          6 | 1000000004 | ccccabc | a    |
|          7 | 1000000005 |         | aa   |
|          8 |            | aaa     | aa   |
|          9 | 1000000001 | abc     | a1   |
| 2147483647 | 1000000003 | abc     | a2   |
+------------+------------+---------+------+
8 rows in set (0.00 sec)mysql>

643ec9224b88d1c1614537ab29d19993.jpeg

结果: 会以截断的方式插入(int的最大值)

4.  结语

总的来说,IGNORE 提供了一种在插入或更新时处理主键、唯一键冲突、非空约束字段未赋值、字段超长等异常时内部自动处理的方法,使得操作不因为某一行的冲突而中断,而是继续处理。但也因为其特点,会导致结果与预期不符的情况。在实际操作中还是建议使用正常的方式进行处理,以免出现不必要的故障。

026d8e662fb4ce678ed9a66afc029aeb.jpeg

往期精彩回顾

1.  MySQL高可用之MHA集群部署

2.  mysql8.0新增用户及加密规则修改的那些事

3.  比hive快10倍的大数据查询利器-- presto

4.  监控利器出鞘:Prometheus+Grafana监控MySQL、Redis数据库

5.  PostgreSQL主从复制--物理复制

6.  MySQL传统点位复制在线转为GTID模式复制

7.  MySQL敏感数据加密及解密

8.  MySQL数据备份及还原(一)

9.  MySQL数据备份及还原(二)

66b5d74f70a6738a28e335918cbc575d.jpeg

扫码关注     

37cd23058a49b128a5e0153747021189.jpeg

cb52dde70023e92e871223a4db72178a.jpeg

a4b7bbca9cf8ad293b2d3aa53298068e.jpeg


http://www.ppmy.cn/news/1248200.html

相关文章

2023关键事件

情境/背景: SAP系统未提供配置BOM解析功能,多个业务部长多次开会强调系统没有配置BOM查询功能,严重影响供应链物料管理。目标/任务: 实现SAP系统中配置BOM解析功能自开发定制程序行动/举措: 花费大量业余时间&#xff…

命令模式 rust和java实现

文章目录 命令模式介绍javarustrust仓库 命令模式 命令模式(Command Pattern)是一种数据驱动的设计模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象&…

C语言——数字金字塔

实现函数输出n行数字金字塔 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>void pyramid(int n) {int i,j,k;for (i1; i<n; i){//输出左边空格&#xff0c;空格数为n-i for (j1; j<n-i; j){printf(" "); } //每一行左边空格输完后输出数字&#…

重工业ERP包含哪些模块?能为企业带来哪些优势

化工、五金、重型机械制造等重工业行业的经营管理模式存在明显的差别化&#xff0c;企业内部的盘点、发货、接单、报价、委外、排产、派工单、工艺、品检等各业务数据的实时和准确共享有利于企业清晰掌握运作情况&#xff0c;及时制定经营策略&#xff0c;提高对市场变化的反应…

1、windows10系统下Qt5.12.0与卸载

一、安装包下载 1、Qt社区下载 https://download.qt.io/archive/qt/5.12/5.12.10/qt-opensource-windows-x86-5.12.10.exe 2、百度网盘下载 链接&#xff1a;百度网盘 请输入提取码 3、Qt官网下载&#xff1a; Try Qt | 开发应用程序和嵌入式系统 | Qt 二、安装提示 下…

Git——Git应用入门

将会介绍以下知识&#xff1a; 搭建Git环境和创建Git版本库&#xff08;init、clone&#xff09;。文件添加、状态检查、创建注释和查看历史记录。与其他Git版本库交互&#xff08;pull、push&#xff09;。解决合并冲突。创建分支列表、列表切换和合并。创建标签。 1、版本控…

34.基于webpack搭建开发环境

一、webpack配置问题 webpack确实强大&#xff0c;但是配置loader、plugin也确实存在与node、npm、webpack版本之间存在冲突的问题&#xff08;真正的从入门到放弃&#xff09;。为了方便平时的开发&#xff0c;我基于webpack4.x 整合了react、vue3、ts开发环境&#xff0c;支持…

法线制作神器crazybump 和 Normal Map Generator

UE4系列文章目录 文章目录 UE4系列文章目录前言一、crazybump是什么&#xff1f;二、Normal Map Generator是什么&#xff1f; 前言 我们在使用UE4、UE5制作材质时&#xff0c;经常会遇到使用法线图。使用深度图生成法线图&#xff0c;一般会使用photoShop等软件&#xff0c;对…