Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle相当于MySQL插入忽略?_Oracle_Insert_Duplicates - Fatal编程技术网

Oracle相当于MySQL插入忽略?

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

我需要更新查询,以便它在插入之前检查重复条目是否不存在。在MySQL中,我可以使用INSERT IGNORE,这样,如果发现重复的记录,它就会跳过INSERT,但我似乎找不到Oracle的等效选项。有什么建议吗?

我认为没有,但为了节省时间,您可以尝试插入并忽略不可避免的错误:

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');