Oracle相当于MySQL插入忽略?
我需要更新查询,以便它在插入之前检查重复条目是否不存在。在MySQL中,我可以使用INSERT IGNORE,这样,如果发现重复的记录,它就会跳过INSERT,但我似乎找不到Oracle的等效选项。有什么建议吗?我认为没有,但为了节省时间,您可以尝试插入并忽略不可避免的错误:Oracle相当于MySQL插入忽略?,oracle,insert,duplicates,Oracle,Insert,Duplicates,我需要更新查询,以便它在插入之前检查重复条目是否不存在。在MySQL中,我可以使用INSERT IGNORE,这样,如果发现重复的记录,它就会跳过INSERT,但我似乎找不到Oracle的等效选项。有什么建议吗?我认为没有,但为了节省时间,您可以尝试插入并忽略不可避免的错误: begin insert into table_a( col1, col2, col3 ) values ( 1, 2, 3 ); exception when dup_val_on_index th
begin
insert into table_a( col1, col2, col3 )
values ( 1, 2, 3 );
exception when dup_val_on_index then
null;
end;
/
这只会忽略由重复主键或唯一键约束引起的异常;其他一切都将正常进行
如果不想这样做,则必须首先从表中进行选择,这并不是很有效。检查MERGE语句。这应该做你想做的事情-当不匹配时,
子句将做这件事
针对Oracle缺乏对true VALUES()子句的支持,使用固定值的单个记录的语法非常笨拙:
MERGE INTO your_table yt
USING (
SELECT 42 as the_pk_value,
'some_value' as some_column
FROM dual
) t on (yt.pk = t.the_pke_value)
WHEN NOT MATCHED THEN
INSERT (pk, the_column)
VALUES (t.the_pk_value, t.some_column);
另一种方法(例如,如果您从不同的表进行批量加载)是使用Oracle的“错误日志”功能。声明如下:
INSERT INTO your_table (col1, col2, col3)
SELECT c1, c2, c3
FROM staging_table
LOG ERRORS INTO errlog ('some comment') REJECT LIMIT UNLIMITED;
之后,表errlog
中提供了可能引发错误的所有行。在使用DBMS\u errlog.create\u ERROR\u LOG
运行insert之前,需要手动创建errlog
表(或您选择的任何名称)
有关详细信息,请参阅手册简单地添加一个索引,其中包含需要检查重复的任何字段,并说它必须是唯一的,如何?保存读取检查。如果您使用的是11g,则可以使用提示:
简单的解决办法
insert into t1
select from t2
where not exists
(select 1 from t1 where t1.id= t2.id)
另一种变体
Insert into my_table (student_id, group_id)
select distinct p.studentid, g.groupid
from person p, group g
where NOT EXISTS (select 1
from my_table a
where a.student_id = p.studentid
and a.group_id = g.groupid)
或者你也可以
Insert into my_table (student_id, group_id)
select distinct p.studentid, g.groupid
from person p, group g
MINUS
select student_id, group_id
from my_table
这不是我的,但在使用sqlloader时非常方便:
创建指向表的视图:
CREATE OR REPLACE VIEW test_view
AS SELECT * FROM test_tab
创建触发器:
CREATE OR REPLACE TRIGGER test_trig
INSTEAD OF INSERT ON test_view
FOR EACH ROW
BEGIN
INSERT INTO test_tab VALUES
(:NEW.id, :NEW.name);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN NULL;
END test_trig;
在ctl文件中,插入到视图中:
OPTIONS(ERRORS=0)
LOAD DATA
INFILE 'file_with_duplicates.csv'
INTO TABLE test_view
FIELDS TERMINATED BY ','
(id, field1)
还有一个“不存在的地方”-使用双变量的变体
insert into t1(id, unique_name)
select t1_seq.nextval, 'Franz-Xaver' from dual
where not exists (select 1 from t1 where unique_name = 'Franz-Xaver');
日志错误仍然会对唯一键或主键冲突引发异常,除非情况发生了变化:@ShannonSeverance:它确实适用于INSERT
s,这正是坏程序员所要求的。但是感谢你的链接,我不知道它不适用于PK的更新(我只使用它进行插入)是否应该用USING
关键字替换FROM
关键字?查看if needed.FYI,您还可以使用一个MERGE-INTO语句复制多行。您可以在不匹配时插入,也可以在匹配时进行更新。谢谢您的帮助!但这似乎是一个非标准的解决方案。。就像任何人都不会记住这个符号一样。@SonicSoul你是对的,这是一种不寻常的编码方式。手册甚至指出,提示通常没有语义效果。像所有提示一样,这一条需要小心使用。例如,如果提示拼写错误,则不会出现编译时错误,这项功能只是默默地不起作用。是的,我最近参加了Oracle开发,对于使用sql实现我以前认为简单的功能的大量技巧感到非常困惑:)对于性能来说,这似乎是个坏主意,因为如果存在重复项,插入将失败,实际上,您可能只想跳过它们。尝试使用jdbc,即使pk被违反,executeUpdate()
返回了1
,我希望它返回0,因为没有更新任何行。这使我无法理解在使用此函数进行插入时是否插入了新数据。如果您想从辅助编程语言@AlikElzin中识别PK冲突,那么这个问题对您来说是错误的。只需执行插入操作
,并捕获您使用的任何语言中的任何异常。此问题的每个答案都将返回1
。
insert into t1(id, unique_name)
select t1_seq.nextval, 'Franz-Xaver' from dual
where not exists (select 1 from t1 where unique_name = 'Franz-Xaver');