精华内容
下载资源
问答
  • 当数据库中存量数据较多,或者是在批量插入操作,很容易出现插入重复数据的问题。 一、三种方法 在 mysql 中,当存在主键冲突或唯一键冲突的情况下,根据插入策略不同,一般有以下三种避免方法: insert...

    本文内容仅在 MariaDB-10.2.15 版本下验证,其它环境下可能略有差异。

    当数据库中存量数据较多时,或者是在批量插入操作时,很容易出现插入重复数据的问题。

    一、三种方法

    在 mysql 中,当存在主键冲突或唯一键冲突的情况下,根据插入策略不同,一般有以下三种避免方法:

    • insert ignore into:若没有则插入,若存在则忽略
    • replace into:若没有则正常插入,若存在则先删除后插入
    • insert into ... on duplicate key update:若没有则正常插入,若存在则更新

    注意,使用以上方法的前提是表中有一个 PRIMARY KEYUNIQUE 约束/索引,否则,使用以上三个语句没有特殊意义,与使用单纯的 INSERT INTO 效果相同。

    在具体介绍三种方法的使用方式之前,均使用如下语句初始化表数据:

    "-- 创建表 ljtest --"
    CREATE TABLE IF NOT EXISTS ljtest (
    id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,  -- 自增主键 id
    emp_no INT(11) NOT NULL,
    title VARCHAR(50) NOT NULL,
    from_date DATE NOT NULL,
    to_date DATE DEFAULT NULL)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    
    "-- 插入三条数据 --"
    INSERT INTO ljtest VALUES 
    ('1', '10001', 'Senior Engineer', '1986-06-26', '9999-01-01'),
    ('2', '10002', 'Staff', '1996-08-03', '9999-01-01'),
    ('3', '10003', 'Senior Engineer', '1995-12-03', '9999-01-01'),
    
    "-- 查看表数据 --"
    select * from ljtest;
    +----+--------+-----------------+------------+------------+
    | id | emp_no | title           | from_date  | to_date    |
    +----+--------+-----------------+------------+------------+
    |  1 |  10001 | Senior Engineer | 1986-06-26 | 9999-01-01 |
    |  2 |  10002 | Staff           | 1996-08-03 | 9999-01-01 |
    |  3 |  10003 | Senior Engineer | 1995-12-03 | 9999-01-01 |
    +----+--------+-----------------+------------+------------+
    3 rows in set (0.00 sec)
    
    "-- 查看此时初始状态下的表结构 --"
    show create table ljtest\G
    *************************** 1. row ***************************
           Table: ljtest
    Create Table: CREATE TABLE `ljtest` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `emp_no` int(11) NOT NULL,
      `title` varchar(50) NOT NULL,
      `from_date` date NOT NULL,
      `to_date` date DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    注意: 初始状态下 AUTO_INCREMENT=4

    一、insert ignore into

    1、作用

    • insert ignore 会根据主键或者唯一键判断,忽略数据库中已经存在的数据
    • 若数据库没有该条数据,就插入为新的数据,跟普通的 insert into 一样
    • 若数据库有该条数据,就忽略这条插入语句,不执行插入操作。

    2、主键冲突情况

    1. 同时向表中插入两条包含主键的数据:id = 2(表中已有),id = 4(表中没有)

    > insert ignore into ljtest(id, emp_no) values (2, 20002), (4, 40004);       
    Query OK, 1 row affected, 3 warnings (0.00 sec)
    Records: 2  Duplicates: 1  Warnings: 3
    

    注意:

    • insert ignore into 与普通 insert into 的使用方法几乎完全一样
      • 插入时要么指定插入的具体列,要么不指定列名插入全部列值,要么对字段加有默认值
      • 否则会报错:
        • ERROR 1136 (21S01): Column count doesn't match value count at row 1
        • ERROR 1364 (HY000): Field 'title' doesn't have a default value
    • 注意插入后返回的信息:
      • 1 row affected:插入成功一条数据
      • 3 warnings:有三条警告信息
      • Duplicates: 1:有一条重复数据

    2. 查看 warning 警告信息

    > show warnings;
    +---------+------+------------------------------------------------+
    | Level   | Code | Message                                        |
    +---------+------+------------------------------------------------+
    | Warning | 1364 | Field 'title' doesn't have a default value     |
    | Warning | 1364 | Field 'from_date' doesn't have a default value |
    | Warning | 1062 | Duplicate entry '2' for key 'PRIMARY'          |
    +---------+------+------------------------------------------------+
    3 rows in set (0.00 sec)
    

    其中的关键信息就是告诉我们主键为 2 的数据重复了。

    3. 查看插入后的表数据

    > select * from ljtest;
    +----+--------+-----------------+------------+------------+
    | id | emp_no | title           | from_date  | to_date    |
    +----+--------+-----------------+------------+------------+
    |  1 |  10001 | Senior Engineer | 1986-06-26 | 9999-01-01 |
    |  2 |  10002 | Staff           | 1996-08-03 | 9999-01-01 |
    |  3 |  10003 | Senior Engineer | 1995-12-03 | 9999-01-01 |
    |  4 |  40004 |                 | 0000-00-00 | NULL       |
    +----+--------+-----------------+------------+------------+
    4 rows in set (0.00 sec)
    

    其中,id = 2 的记录还是之前的数据,id = 4 的数据是新插入的。

    即,insert ignore into 会忽略已存在数据(按主键或唯一键判断),只插入新数据。

    4. 查看插入后的表结构

    > show create table ljtest\G
    *************************** 1. row ***************************
           Table: ljtest
    Create Table: CREATE TABLE `ljtest` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `emp_no` int(11) NOT NULL,
      `title` varchar(50) NOT NULL,
      `from_date` date NOT NULL,
      `to_date` date DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    注意: 插入后 AUTO_INCREMENT=5 (从初始 4 增加为 5),这是正常的。

    3、唯一键冲突情况

    先重建表数据,对 emp_no 字段增加 unique 约束,并初始化同样的三条数据。

    1. 向表中插入一条包含唯一键冲突的数据:emp_no = 10003(表中已有)

    insert ignore ljtest(emp_no, title, from_date) values (10003, 'ignore test 3', '0000-00-00');
    
    Query OK, 0 rows affected, 1 warning (0.00 sec)
    

    2. 查看插入后的表数据

    跟原数据一样,未发生任何变化。

    3. 查看插入后的表结构

    > show create table ljtest\G
    *************************** 1. row ***************************
           Table: ljtest
    Create Table: CREATE TABLE `ljtest` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `emp_no` int(11) NOT NULL,
      `title` varchar(50) NOT NULL,
      `from_date` date NOT NULL,
      `to_date` date DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `emp_no` (`emp_no`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    注意: 虽然未插入成功,但 AUTO_INCREMENT=5 (从初始 4 增加为 5),再次新增数据时,id 将会从 5 开始。

    二、insert into ... on duplicate key update

    1、作用

    • insert into 语句末尾指定 on duplicate key update,会根据主键或者唯一键判断:
      • 若数据库有该条数据,则直接更新原数据,相当于 update
      • 若数据库没有该条数据,则插入为新的数据,跟普通的 insert into 一样

    2、主键冲突情况

    1. 同时向表中插入两条包含主键的数据:id = 2(表中已有),id = 4(表中没有)

    > insert into ljtest(id, emp_no, title, from_date) values (2, 20002, 'insert test 2', '0000-00-00'), (4, 40004, 'insert test 4', '0000-00-00') on duplicate key update emp_no=values(emp_no), title=values(title);           
    
    Query OK, 3 rows affected (0.00 sec)
    Records: 2  Duplicates: 1  Warnings: 0
    

    其中:

    • 与普通 insert into 的使用语法差别不大,只是语句结尾有所区别
    • emp_no=values(emp_no), title=values(title)
      • 表示当存在主键或唯一键冲突时,使用插入语句中对应的 emp_notitle 值替换原数据
      • 同时,还可以通过运算表达式来指定字段值,如:emp_no=emp_no+1, title=title+"test"
    • 因为这里未指定 update from_date 字段,所以当 id 重复时,不会更新 from_date 字段。
    • 3 row affected
      • 插入一条数据,受影响的行为 1;
      • 表中原有记录被更新,受影响的行计为 2。

    2. 查看插入后的表数据

    > select * from ljtest;
    +----+--------+-----------------+------------+------------+
    | id | emp_no | title           | from_date  | to_date    |
    +----+--------+-----------------+------------+------------+
    |  1 |  10001 | Senior Engineer | 1986-06-26 | 9999-01-01 |
    |  2 |  20002 | insert test 2  | 1996-08-03 | 9999-01-01 |
    |  3 |  10003 | Senior Engineer | 1995-12-03 | 9999-01-01 |
    |  4 |  40004 | insert test 4  | 0000-00-00 | NULL       |
    +----+--------+-----------------+------------+------------+
    4 rows in set (0.00 sec)
    

    其中,id = 2 的记录中 emp_no 和 title 字段被替换成新的数据,其它字段还是原来的值。
    id = 4 的数据是新插入的。

    3. 查看插入后的表结构

    > show create table ljtest\G     
    *************************** 1. row ***************************
           Table: ljtest
    Create Table: CREATE TABLE `ljtest` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `emp_no` int(11) NOT NULL,
      `title` varchar(50) NOT NULL,
      `from_date` date NOT NULL,
      `to_date` date DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    注意: 插入后 AUTO_INCREMENT=5 (从初始 4 增加为 5),这是正常的。

    3、唯一键冲突情况

    先重建表数据,对 emp_no 字段增加 unique 约束,并初始化同样的三条数据。

    1. 向表中插入一条包含唯一键冲突的数据:emp_no = 10003(表中已有)

    insert into ljtest(emp_no, title, from_date) values (10003, 'insert test 3', '0000-00-00') on duplicate key update title=values(title);
    
    Query OK, 2 rows affected (0.00 sec)
    

    2. 查看插入后的表数据

    +----+--------+-----------------+------------+------------+
    | id | emp_no | title           | from_date  | to_date    |
    +----+--------+-----------------+------------+------------+
    |  1 |  10001 | Senior Engineer | 1986-06-26 | 9999-01-01 |
    |  2 |  10002 | Staff           | 1996-08-03 | 9999-01-01 |
    |  3 |  10003 | insert test 3   | 1995-12-03 | 9999-01-01 |
    +----+--------+-----------------+------------+------------+
    3 rows in set (0.00 sec)
    

    其中,emp_no = 10003 记录的 title 被更新了,但主键 id 不变,即更新了原记录的指定列数据。

    3. 查看插入后的表结构

    > show create table ljtest\G
    *************************** 1. row ***************************
           Table: ljtest
    Create Table: CREATE TABLE `ljtest` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `emp_no` int(11) NOT NULL,
      `title` varchar(50) NOT NULL,
      `from_date` date NOT NULL,
      `to_date` date DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    注意: 插入后 AUTO_INCREMENT=5 (从初始 4 增加为 5),再次新增数据时,id 将会从 5 开始。

    三、replace into

    1、作用

    • replace into 会根据主键或者唯一键判断:
      • 若表中已存在该数据,则先删除此行数据,然后插入新的数据,相当于 delete + insert
        • 可能会丢失数据、主从服务器的 AUTO_INCREMENT 不一致。
      • 若表中不存在该数据,则直接插入新数据,跟普通的 insert into 一样

    2、主键冲突情况

    1. 同时向表中插入两条包含主键的数据:id = 2(表中已有),id = 4(表中没有)

    > replace into ljtest(id, emp_no, title, from_date) values (2, 20002, 'replace test 2', '0000-00-00'), (4, 40004, 'replace test 4', '0000-00-00'); 
    
    Query OK, 3 rows affected (0.00 sec)
    Records: 2  Duplicates: 1  Warnings: 0
    

    注意:

    • replace into 与普通 insert into 的使用语法几乎一样
    • 注意插入后返回的信息:
      • 3 row affected:删除一条数据,插入两条数据
      • Duplicates: 1:有一条重复数据

    2. 查看插入后的表数据

    > select * from ljtest;
    +----+--------+-----------------+------------+------------+
    | id | emp_no | title           | from_date  | to_date    |
    +----+--------+-----------------+------------+------------+
    |  1 |  10001 | Senior Engineer | 1986-06-26 | 9999-01-01 |
    |  2 |  20002 | replace test 2  | 0000-00-00 | NULL       |
    |  3 |  10003 | Senior Engineer | 1995-12-03 | 9999-01-01 |
    |  4 |  40004 | replace test 4  | 0000-00-00 | NULL       |
    +----+--------+-----------------+------------+------------+
    4 rows in set (0.00 sec)
    

    其中,id = 2 的记录被替换成新的数据、且 to_date 字段原数据丢失,id = 4 的数据是新插入的。

    4. 查看插入后的表结构

    > show create table ljtest\G     
    *************************** 1. row ***************************
           Table: ljtest
    Create Table: CREATE TABLE `ljtest` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `emp_no` int(11) NOT NULL,
      `title` varchar(50) NOT NULL,
      `from_date` date NOT NULL,
      `to_date` date DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    注意:插入后 AUTO_INCREMENT=6 (从初始 4 增加为 5),这是正常的。

    3、唯一键冲突情况

    先重建表数据,对 emp_no 字段增加 unique 约束,并初始化同样的三条数据。

    1. 向表中插入一条包含唯一键冲突的数据:emp_no = 10003(表中已有)

    replace into ljtest(emp_no, title, from_date) values (10003, 'replace test 3', '0000-00-00');
    
    Query OK, 2 rows affected (0.00 sec)
    

    2. 查看插入后的表数据

    +----+--------+-----------------+------------+------------+
    | id | emp_no | title           | from_date  | to_date    |
    +----+--------+-----------------+------------+------------+
    |  1 |  10001 | Senior Engineer | 1986-06-26 | 9999-01-01 |
    |  2 |  10002 | Staff           | 1996-08-03 | 9999-01-01 |
    |  4 |  10003 | replace test 3  | 0000-00-00 | NULL       |
    +----+--------+-----------------+------------+------------+
    3 rows in set (0.00 sec)
    

    其中,emp_no = 10003 记录的 title 被更新了,同时主键 id 也变成 4 ,即执行了 delete + insert 操作。

    3. 查看插入后的表结构

    > show create table ljtest\G
    *************************** 1. row ***************************
           Table: ljtest
    Create Table: CREATE TABLE `ljtest` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `emp_no` int(11) NOT NULL,
      `title` varchar(50) NOT NULL,
      `from_date` date NOT NULL,
      `to_date` date DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    注意: 插入后 AUTO_INCREMENT=5 (从初始 4 增加为 5),再次新增数据时,id 将会从 5 开始。

    总结:

    • 在主键冲突情况下,三种方法都可以使用
    • 在唯一键冲突情况下,且有自增主键时:
      • 三种方法都会出现 AUTO_INCREMENT 不连续问题,且这种不连续不会同步更新到 slave 的 AUTO_INCREMENT
        • 当 master 被 kill,且 slave 升级为 master 时,就会出现主键冲突问题。
    • replace into 方法可能会导致部分数据丢失。

    所以,实际使用时,若是唯一键冲突的情况,一定要谨慎,避免踩坑!

    展开全文
  • Mysql批量插入数据时如何解决重复问题? 前两天写代码遇到如果有相同数据就删除,采用新传入的数据,当时着急就用的delete+insert。今天有空就问了下度娘,感觉很有用,记录下来。 三种方法如下: 使用以上方法的...

    Mysql批量插入数据时如何解决重复问题?


    前两天写代码遇到如果有相同数据就删除,采用新传入的数据,当时着急就用的delete+insert。今天有空就问了下度娘,感觉很有用,记录下来。

    三种方法如下:

    使用以上方法的前提是表中有一个 PRIMARY KEY 或 UNIQUE 约束/索引,否则,使用以上三个语句没有特殊意义,与使用单纯的 INSERT INTO 效果相同。

    A、insert ignore into(若没有则插入,若存在则忽略)
    作用:
    insert ignore 会根据主键或者唯一键判断,忽略数据库中已经存在的数据
    若数据库没有该条数据,就插入为新的数据,跟普通的 insert into 一样
    若数据库有该条数据,就忽略这条插入语句,不执行插入操作。

    B、insert into ... on duplicate key update(若没有则正常插入,若存在则更新)
    作用:
    在 insert into 语句末尾指定 on duplicate key update,会根据主键或者唯一键判断:
    若数据库有该条数据,则直接更新原数据,相当于 update
    若数据库没有该条数据,则插入为新的数据,跟普通的 insert into 一样。

    C、replace into(若没有则正常插入,若存在则先删除后插入)
    作用:
    replace into 会根据主键或者唯一键判断:
    若表中已存在该数据,则先删除此行数据,然后插入新的数据,相当于 delete + insert
    可能会丢失数据、主从服务器的 AUTO_INCREMENT 不一致。
    若表中不存在该数据,则直接插入新数据,跟普通的 insert into 一样。

    版权声明:本文为CSDN博主「媛测」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/lijing742180/article/details/90243470

    展开全文
  • python MongoDB 插入数据 去除重复数据

    千次阅读 2019-05-14 17:31:19
    最笨的方法呢,就是先把所有的数据插入数据库里,再去除掉多余重复的数据。具体操作呢,繁琐,复杂,效率低,还总容易出现莫名其妙的bug。 最理想的插入方法就是,如果数据库不存在,则插入数据;如果数据已经存在了...

    python 往MongoDB数据库中插入数据,经常会遇到的一个需求就是,对插入的数据进行去重。

    最笨的方法呢,就是先把所有的数据插入数据库里,再去除掉多余重复的数据。具体操作呢,繁琐,复杂,效率低,还总容易出现莫名其妙的bug。

    最理想的插入方法就是,如果数据库不存在,则插入数据;如果数据已经存在了,就不插入数据,或者更新数据。
    使用insert方法,目前还没发现什么去重的好用处
    。 能够更新数据库的就是update()方法了。

    update()方法需要两个参数,fileter,document, fileter 是更新条件, document是更新的内容。

    要实现如果不存在就插入,如果存在就不插入的要求,我们需要用到 update的一个参数:‘$setOnInsert’

    具体的操作方法可以参考九茶大神的这篇博客: https://blog.csdn.net/Bone_ACE/article/details/50696477

    详细介绍了 $setOnInsert 方法的使用规则。

    唯一不足的是,这里只有命令行模式下的规则,现在我们需要的是在python和MongoDB交互过程中使用$setOnInsert参数。

    这个就是我们接下来的重点了。

    python与MongoDB的交互方法和命令行下的MongoDB命令 差不了多少,原理相同,就是具体的方法可能有些差异。

    update方法的源码具体如下:
    在这里插入图片描述

    $setOnInsert官方文档的介绍如下:

    在这里插入图片描述

    通过阅读官方文档我们可以发现 与$setOnInsert方法想配合的最重要的参数就是 upsert:True。

    update源码中的upsert参数默认为False,只需要将update方法的upsert参数修改为True是否就能达到需要的效果呢?

    在这里插入图片描述
    开始时MongoDB数据库为空,执行update方法以后,数据库存在我们插入的标签数据,多次执行update方法,数据库的标签数据也不会增加。

    理论上来说,update() 能够使用的 $setOnInsert 方法, update_many() 批量修改MongoDB也能够修改, update_many()函数中同样存在upsert参数。

    具体实验却是失败的。

    如果有哪位小伙伴知道update_many() 的使用方法,麻烦留言交流一下,万分感谢。

    展开全文
  • sqlite避免重复插入数据

    热门讨论 2013-07-10 13:33:11
    网上收集的sqlite避免重复插入数据
  • oracle 批量插入时,如何去除重复数据

    千次阅读 2017-06-06 23:44:46
    用储存过程批量抽取一个视图的数据,插入到一个新建的表,视图数据有2.4亿,昨天抽取到6千万就卡住了,不知道什么原因,想继续执行这个存储过程,想请问加什么条件来避免插入那些已经插入过的数据 视图上有唯一性字段 XH...

    用储存过程批量抽取一个视图的数据,插入到一个新建的表,视图数据有2.4亿,昨天抽取到6千万就卡住了,不知道什么原因,想继续执行这个存储过程,想请问加什么条件来避免插入那些已经插入过的数据

    视图上有唯一性字段  XH

    储存过程如下

    create or replace procedure up_table as

    type a is table of new_table%rowtype;

    in_data a;

    i number;

    cursor c is select * from fcd_ci_gps@dblink;

    begin

            open c;

            loop

            fetch c bulk collect into in_data limit 5000;

            forall i in 1..in_data.count

            insert into new_table values in_data(i);

            commit;

            exit when in_data.count=0;

            end loop;

            close c;
    end;







    最近刚做了一个你说的类似需求: 

    我的业务需求是, 
    从oracle数据库中获取数据,然后同步到sqlserver中。 

    首先是配置两个数据库之间的连接设置。 
    我是sqlserver 连接oracle 配置sqlserver的链路服务器就OK。 

    下面是存储过程的内容了: 

    1. 创建临时表。 

    通过远程连接,insert into 临时表  select  远程表  。 
    获取数据先到本地,。 

    然后用 临时表的数据,跟你本地业务表的数据进行对比。 
    查询不通的数据。 

    Java代码   收藏代码
    1. -- (1) 远程读取NC需求计划,分组汇总数据后,插入到临时表 #tmp_pl_plan中。  
    2.     set @InsertStrSQL = @InsertStrSQL@tmpStrSQl;  
    3.     print(@InsertStrSQL) ;  
    4.     exec(@InsertStrSQL);  
    5.       
    6.     select @tmpCont = count(1) from #tmp_pl_plan ;  
    7.       
    8.     -- state:0新增、1修改、2删除  
    9.     -- (2) 用本地数据与临时表中的数据,进行对比,更新本地表中计划数量与临时表中不相等的记录.  
    10.          
    11.         update t set t.plnum  = a.plnum ,t.state = 1  
    12.         from  #tmp_pl_plan a,NC_PL_PLAN t   
    13.         where a.factorycode = t.factorycode and a.weldingdate = t.weldingdate  
    14.         and a.divisions = t.divisions and a.zzmadeline = t.zzmadeline   
    15.         and a.zzweldingwayCode  = t.zzweldingwayCode and a.zzmadelinetypeCode = t.zzmadelinetypeCode  
    16.         and a.convertedcode = t.convertedcode and  a.ncfprocode = t.ncfprocode    
    17.         and t.plnum != a.plnum    
    18.         and t.weldingdate >=  @fbegdate and t.weldingdate <= @fenddate   
    19.       
    20.     -- (3) 对比数据,查找本地表中存在,但是临时表中不存在的记录,然后修改本地表中的数量=0 ,state = 3 表示删除  
    21.         update t set t.plnum = 0 ,t.state = 2    
    22.         from NC_PL_PLAN t  
    23.         where t.weldingdate between  @fbegdate and @fenddate   
    24.         and not exists (  
    25.             select 1 from  #tmp_pl_plan a where a.factorycode = t.factorycode and a.weldingdate = t.weldingdate  
    26.             and a.divisions = t.divisions and a.zzmadeline = t.zzmadeline   
    27.             and a.zzweldingwayCode  = t.zzweldingwayCode and a.zzmadelinetypeCode = t.zzmadelinetypeCode  
    28.             and a.convertedcode = t.convertedcode  and a.ncfprocode = t.ncfprocode  
    29.               
    30.         );  
    31.   
    32.       
    33.     -- (4) 对比数据,新增临时表中不存在于当前表的数据  
    34.     --delete    NC_PL_PLAN;  
    35.     insert into NC_PL_PLAN   
    36.     select * from #tmp_pl_plan t  
    37.     where t.weldingdate between  @fbegdate and @fenddate   
    38.     and not exists (  
    39.         select 1 from   NC_PL_PLAN a where a.factorycode = t.factorycode and a.weldingdate = t.weldingdate  
    40.         and a.divisions = t.divisions and a.zzmadeline = t.zzmadeline   
    41.         and a.zzweldingwayCode  = t.zzweldingwayCode and a.zzmadelinetypeCode = t.zzmadelinetypeCode  
    42.         and a.convertedcode = t.convertedcode and a.ncfprocode = t.ncfprocode  
    43.         and a.weldingdate >=  @fbegdate and a.weldingdate<= @fenddate   
    44.     )  
    45.     order by t.weldingdate desc ;  

    最近刚做了一个你说的类似需求: 

    我的业务需求是, 
    从oracle数据库中获取数据,然后同步到sqlserver中。 

    首先是配置两个数据库之间的连接设置。 
    我是sqlserver 连接oracle 配置sqlserver的链路服务器就OK。 

    下面是存储过程的内容了: 

    1. 创建临时表。 

    通过远程连接,insert into 临时表  select  远程表  。 
    获取数据先到本地,。 

    然后用 临时表的数据,跟你本地业务表的数据进行对比。 
    查询不通的数据。 

    Java代码   收藏代码
    1. -- (1) 远程读取NC需求计划,分组汇总数据后,插入到临时表 #tmp_pl_plan中。  
    2.     set @InsertStrSQL = @InsertStrSQL@tmpStrSQl;  
    3.     print(@InsertStrSQL) ;  
    4.     exec(@InsertStrSQL);  
    5.       
    6.     select @tmpCont = count(1) from #tmp_pl_plan ;  
    7.       
    8.     -- state:0新增、1修改、2删除  
    9.     -- (2) 用本地数据与临时表中的数据,进行对比,更新本地表中计划数量与临时表中不相等的记录.  
    10.          
    11.         update t set t.plnum  = a.plnum ,t.state = 1  
    12.         from  #tmp_pl_plan a,NC_PL_PLAN t   
    13.         where a.factorycode = t.factorycode and a.weldingdate = t.weldingdate  
    14.         and a.divisions = t.divisions and a.zzmadeline = t.zzmadeline   
    15.         and a.zzweldingwayCode  = t.zzweldingwayCode and a.zzmadelinetypeCode = t.zzmadelinetypeCode  
    16.         and a.convertedcode = t.convertedcode and  a.ncfprocode = t.ncfprocode    
    17.         and t.plnum != a.plnum    
    18.         and t.weldingdate >=  @fbegdate and t.weldingdate <= @fenddate   
    19.       
    20.     -- (3) 对比数据,查找本地表中存在,但是临时表中不存在的记录,然后修改本地表中的数量=0 ,state = 3 表示删除  
    21.         update t set t.plnum = 0 ,t.state = 2    
    22.         from NC_PL_PLAN t  
    23.         where t.weldingdate between  @fbegdate and @fenddate   
    24.         and not exists (  
    25.             select 1 from  #tmp_pl_plan a where a.factorycode = t.factorycode and a.weldingdate = t.weldingdate  
    26.             and a.divisions = t.divisions and a.zzmadeline = t.zzmadeline   
    27.             and a.zzweldingwayCode  = t.zzweldingwayCode and a.zzmadelinetypeCode = t.zzmadelinetypeCode  
    28.             and a.convertedcode = t.convertedcode  and a.ncfprocode = t.ncfprocode  
    29.               
    30.         );  
    31.   
    32.       
    33.     -- (4) 对比数据,新增临时表中不存在于当前表的数据  
    34.     --delete    NC_PL_PLAN;  
    35.     insert into NC_PL_PLAN   
    36.     select * from #tmp_pl_plan t  
    37.     where t.weldingdate between  @fbegdate and @fenddate   
    38.     and not exists (  
    39.         select 1 from   NC_PL_PLAN a where a.factorycode = t.factorycode and a.weldingdate = t.weldingdate  
    40.         and a.divisions = t.divisions and a.zzmadeline = t.zzmadeline   
    41.         and a.zzweldingwayCode  = t.zzweldingwayCode and a.zzmadelinetypeCode = t.zzmadelinetypeCode  
    42.         and a.convertedcode = t.convertedcode and a.ncfprocode = t.ncfprocode  
    43.         and a.weldingdate >=  @fbegdate and a.weldingdate<= @fenddate   
    44.     )  
    45.     order by t.weldingdate desc ;  



    第一:merge into 就是最快的表更新方案了,merge into 能够去除重复数据,插入新数据,我不知道你为什么不用merge into。

    第二: 如果你不信任merge into,那么你可以在被更新的数据表中对唯一标识的列建立索引(index),这样你在直接使用游标将一个表对另外一个表更新的时候会快很多很多。


    展开全文
  • Mysql批量插入时重复数据问题

    千次阅读 2020-04-15 16:31:57
    之前写的代码批量插入遇到了问题,原因是有重复数据(主键或唯一索引冲突),所以插入失败。现在总结一下如何解决批量插入数据重复问题。 三种方法: insert ingnore into:若没有则插入,若存在则忽略 insert ...
  • 数据存储过程中,可能会遇到数据主键重复的情况,我们可以通过下面几个方法进行处理:  ...2. 使用duplicate key关键字,如插入数据时发生主键冲突就更新数据  3. 使用Ingore关键字  4. 使用repl
  • 插入数据的时候防止重复数据插入

    千次阅读 2019-02-25 13:50:36
    在SQLITE中,可以用以下方法防止插入重复数据, 1.设置表的联合主键 2.在INSERT语句中添加OR IGNORE,即可(重复数据会跳过,且不影响后续数据插入) 示例如下: insert OR IGNORE into PDA_Test (DeviceID,...
  • 1.使用MySQL设置主键需要注意以下问题: (1)如果主键类型是int,可以直接设置主键自增 ...2.该报错问题是插入数据表中遇到键重复,解决方案如下: (1)IGNORE 例如:INSERT IGNORE INTO Table_name(…..) VALU...
  • Mysql插入重复数据,当大数据量的数据需要插入,要判断插入是否重复,然后再插入,那么如何提高效率?解决的办法有很多种,不同的场景解决方案也不一样,数据量很小的情况下,怎么搞都行,但是数据量很大的...
  • db2 批量插入数据去重复

    千次阅读 2018-05-08 19:29:38
    开发过程遇到 两张表字段相同,但是需要将旧表数据插入新表,如果新表已有此数据则不予插入。第一种方法select * from TA_TRL_GO_COMEBILL A left join ( SELECT S_BOOKORGCODE,S_MSGID,S_BNKNO FROM TA_TRL_HVPS_...
  • sql插入数据时,避免插入重复数据

    万次阅读 2016-11-23 13:18:27
    1.往表T_Mid_WaterIndexArea中插入数据  insert into [dbo].[T_Mid_WaterIndexArea](AreaCode,Year,DO,CODMn,BOD5,COD,NH3N,TP,TN,CompositeIndex) select c.AreaCode,c.Year, --c.AreaName, AVG(c.DO) DO,AVG(c....
  • 现在我有一个JOB,用于同步一个表的数据,在执行插入和更新的时候出现了同步数据, 大神们求帮助,转换与JOB设置如下 ![转换](https://img-ask.csdn.net/upload/201709/07/1504751041_343521.png) ![获取最大执行...
  • 那么问题来了,当出现并发,两个线程会同时查询该记录,都发现没有数据,然后都插入,那么有一条的插入 SQL 就会报错。 ERROR 1062 (23000): Duplicate entry '01' for key 'uk_qq_group_number' 报错会导致...
  • mysql批量插入数据时,会存在重复数据的可能. 可以通过1)数据库加联合索引 2)修改sql,忽略重复数据,防止数据库报错 1. CREATE TABLE `merchantBlackList` ( `id` int(5) NOT NULL AUTO_INCREMENT, `createTime` ...
  • 为啥要解决数据重复插入? 解决方案实战 可落地小总结 一、为啥要解决数据重复插入? 问题起源,微信小程序抽风 wx.request() 重复请求服务器提交数据。后端服务也很简单,伪代码如下: class SignLogService {...
  • 这是一个之前做项目用的。 以下是触发器sql语句,直接执行即可。如果需求不一样需要修改对应的语句就行。 USE [NetCoreWebApi] GO /****** Object: Trigger [dbo].[testInsertTrigger] Script Date: 2020/2/23/...
  • 问题描述:用Scrapy来爬取某论坛数据,在数据导入mysql数据库中,一直有个别数据重复插入。 修改之前代码: class AyncMysqlPipeline(object): # 初始化数据库连接 def __init__(self): dbparms = dict( host...
  • 重复插入数据的另类解决思路

    千次阅读 2015-12-08 17:45:32
    在进行插入数据时,我们会先从数据库查询是否已经拥有该记录,但是最后会发现这个判断没有任何效果,导致这个判断失效的原因有很多,比如事务没有提交,或者多台服务器都执行了相同的代码,或者你的控制器(strut2的...
  • 如何避免MySql数据库的重复插入数据

    千次阅读 2020-09-10 14:51:45
    通常我们需要避免数据库重复插入操作的时候会给表设置主键或唯一索引,当插入重复数据的时候抛出异常,程序终止,但是这样也会存在一定的麻烦,所以就需要我们能尽量的避开或忽略异常。为了演示,我们新建一个User...
  • 其实insert不止可以传入一个参数, 查看源码可知道, 只要第二个字段传入true, 如果遇到重复数据那么tp就是更新这条数据而不是 插入数据. 同时注意要一个字段唯一的这样才会触发数据重复条件,(比如某个字段设置了...
  • mysql数据库中避免重复数据插入

    万次阅读 2018-06-29 15:42:20
    修改sql语句在插入时 避免重复插入 网上看了几个博客都是设置唯一索引 使用ignore或者REPLACE INTO 或者ON DUPLICATE KEY UPDATE https://www.cnblogs.com/Eric-zhao/p/6655994.html http...
  • --防止插入重复数据,采用插入判断--&gt; &lt;insert id="insertVariant" parameterType="com.wwx.datasynchronizer.entity.mingnew.VariantBean"&gt; INSERT IGNORE INTO ...
  • MySQL为我们解决了这个问题:...在DUPLICATE KEY UPDATE上可以达到以下目的:向数据库中插入一条记录:若该数据的主键值/ UNIQUE KEY已经在表中存在,则执行更新操作,即UPDATE后面的操作。否则插入一条新的记录。...
  • 项目使用了 oracle 数据库,在一张设置了主键的表上,主键数据竟然还能插入重复数据。主键的设置包含了唯一键,那么到底是怎么出现这样的情况呢? 原因分析: 数据吧的主键虽然设置了,但是没有启动,这才导致可以...
  • oracle 防止插入重复数据

    千次阅读 2018-06-21 13:24:32
    有时候用oracle的数据库,插入数据的时候需要判断一下该条数据是否已经存在。我们的第一思路如下,首先执行下面这个sql: [sql] view plain copyselect count(*) isExists from t_test_lll; 然后判断...
  • es写数据过程: 客户端向Node(协调节点-coordinating node)发送索引文档请求。 Node对document 进行路由,根据文档ID(_id字段)计算出该文档所属的shard,然后请求路由到对应的 node(有 primary shard)。 实际的...
  • 解决方案:如何防止数据重复插入

    千次阅读 2019-04-24 17:45:08
    业务场景:我们做的是仓库管理系统,产线上需要零件的时候,首先生成一个拉动,我需要把拉动,生成拣货单,然后根据拣货单拣货,上线。 操作流程是:在web上选择多个拉动单,点击组单按钮,即可生产拣货单。 ...
  • SQL多个主键的表,插入数据重复时,会提示违反主键约束不能插入的错误。那么,如何找到插入数据重复值?解决方法:使用group by假设有个表#a,有saleid,vendorid,comid,price,saleprice,quantity等字段。主键是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 560,506
精华内容 224,202
关键字:

数据插入时去重复