41

假设我有一个 Oracle PL/SQL 块,它将记录插入到表中,并且需要从唯一约束错误中恢复,如下所示:

begin
    insert into some_table ('some', 'values');
exception
    when ...
        update some_table set value = 'values' where key = 'some';
end;

是否可以将省略号替换为某些内容以捕获唯一约束错误?

4

4 回答 4

78
EXCEPTION
      WHEN DUP_VAL_ON_INDEX
      THEN
         UPDATE
于 2009-01-13T18:22:36.770 回答
27

我相信你有你的理由,但以防万一......你还应该考虑使用“合并”查询:

begin
    merge into some_table st
    using (select 'some' name, 'values' value from dual) v
    on (st.name=v.name)
    when matched then update set st.value=v.value
    when not matched then insert (name, value) values (v.name, v.value);
end;

(将上述修改为在开始/结束块中;显然您也可以独立于程序运行它)。

于 2009-01-13T18:31:41.963 回答
14

我怀疑你正在寻找的条件是 DUP_VAL_ON_INDEX

EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
        DBMS_OUTPUT.PUT_LINE('OH DEAR. I THINK IT IS TIME TO PANIC!')
于 2009-01-13T18:22:34.370 回答
0

作为显式捕获和处理异常的替代方法,您可以通过/*+ hint */在插入语句中包含 a 来告诉 Oracle 捕获并自动忽略异常。这比显式捕获异常然后阐明应该如何处理它要快一些。它也更容易设置。缺点是您没有从 Oracle 获得任何关于捕获到异常的反馈。

这是一个示例,我们将从另一个表或内部查询中进行选择,并将结果插入一个名为的表中,该表TABLE_NAME对名为 的列具有唯一约束IDX_COL_NAME

INSERT /*+ ignore_row_on_dupkey_index(TABLE_NAME(IDX_COL_NAME)) */ 
INTO TABLE_NAME(
    INDEX_COL_NAME
  , col_1
  , col_2
  , col_3
  , ...
  , col_n)
SELECT 
    INDEX_COL_NAME
  , col_1
  , col_2
  , col_3
  , ...
  , col_n);

如果您的目标是捕获和处理(即打印或更新违反约束的行),这不是一个很好的解决方案。但是,如果您只是想抓住它并忽略违规行,那么这应该可以完成工作。

于 2019-10-06T19:47:46.580 回答