plsql:从select中插入多行并忽略重复项

时间:2014-12-26 14:25:40

标签: oracle plsql

我正在使用带有TOAD的oracle 10g。 我需要使用INSERT FROM SELECT插入大量记录。

BEGIN    
    INSERT INTO MYTABLE(C1,C2,C3)  
    SELECT C1,C2,C3 FROM MYTABLE2 WHERE C1>100;
EXCEPTION    
         WHEN DUP_VAL_ON_INDEX  THEN NULL;    
COMMIT;    
END;

在这里,我面临的问题是,如果此选择查询返回已存在于MYTABLE中的行,那么所有事务都将被回滚。

有没有办法插入所有不存在的行,忽略重复的行并继续插入不存在的行然后提交事务?

4 个答案:

答案 0 :(得分:0)

使用Distinct关键字

BEGIN
    插入到MYTABLE(C1,C2,C3)
    选择不同的C1,C2,C3来自MYTABLE2 WHERE C1> 100; EXCEPTION
         当DUP_VAL_ON_INDEX为空时;
COMMIT;
END;

答案 1 :(得分:0)

您可以首先避免使用这些行,而不是尝试处理异常,例如,使用minus运算符:

INSERT INTO mytable (c1, c2, c3)  
SELECT c1, c2, c3 
FROM   mytable2 
WHERE  c1 > 100;
MINUS
SELECT c1, c2, c3
FROM   mytable
WHERE  c1 > 100 -- not necessary, but should improve performance

答案 2 :(得分:0)

有很多方法可以做到这一点。首先,你可以尝试这样的事情:

insert into mytable(c1, c2, c3)
select distinct c1, c2, c3 from mytable2 where c1 > 100
minus
select c1, c2, c3 from mytable;

否则,您可以使用类似

的内容
insert into mytable(c1, c2, c3)
select c1, c2, c3 from mytable2 where c1 > 100
log errors into myerrtable reject limit unlimited;

等等......

有关错误记录的详细信息。 Feauture自10g第2版开始引入。

SQL> create table garbage(id integer);

Table created

SQL> insert into garbage select rownum from dual connect by level <= 10;

10 rows inserted

SQL> insert into garbage values (3);

1 row inserted

SQL> insert into garbage values (5);

1 row inserted

SQL> create table uniq(id integer not null primary key);

Table created

SQL> insert into uniq select * from garbage;

ORA-00001: unique constraint (TEST.SYS_C0010568) violated

SQL> select count(*) from uniq;

  COUNT(*)
----------
         0

SQL> exec dbms_errlog.create_error_log('uniq', 'uniq_err');

PL/SQL procedure successfully completed

SQL> insert into uniq select * from garbage
  2  log errors into uniq_err reject limit unlimited;

10 rows inserted

SQL> select * from uniq;

                                     ID
---------------------------------------
                                      1
                                      2
                                      3
                                      4
                                      5
                                      6
                                      7
                                      8
                                      9
                                     10

10 rows selected

SQL> select ora_err_mesg$, id from uniq_err;

ORA_ERR_MESG$                                                          ID
---------------------------------------------------------------------- --
ORA-00001: unique constraint (TEST.SYS_C0010568) violated              3
ORA-00001: unique constraint (TEST.SYS_C0010568) violated              5

答案 3 :(得分:0)

我想我会回答这个问题,但这实际上取决于你想要达到的目标。

您可以使用以下方法检查数据是否已在table2中

INSERT INTO mytable2 (c1, c2, c3) 
SELECT DISTINCT c1,c2,c3 FROM mytable t1
WHERE c1 > 100 
AND NOT EXISTS 
(select 1 from mytable2 t2 where t2.c1 = t1.c1 and t2.c2 = t1.c2 and t2.c3 = t1.c3);

或者您可以使用这样的合并:

MERGE INTO mytable2 m2
USING (SELECT DISTINCT c1, c2, c3 FROM mytable) m1 
ON (m1.c1 = m2.c1 and m1.c2 = m2.c2 and m1.c3 = m2.c3) 
WHEN NOT MATCHED THEN INSERT (c1, c2, c3)  VALUES (m1.c1, m1.c2, m1.c3)
where m1.c1 > 100;

在这两个示例中,您只会在mytable2中插入唯一的行