我正在使用带有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中的行,那么所有事务都将被回滚。
有没有办法插入所有不存在的行,忽略重复的行并继续插入不存在的行然后提交事务?
答案 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中插入唯一的行