Oracle

Oracle:如果不存在則插入

  • August 23, 2022

我的問題是 Oracle 數據庫中是否有原子插入如果不存在語句?這不是 ANSI SQL 的一部分,因此每個數據庫供應商都有自己的方法(如果支持)。

要限定語句必須在高並發負載下工作並且永遠不會拋出重複鍵錯誤。該語句必須成功(插入行)或不執行任何操作(PK 值已存在)。

我做了一些Google搜尋,我的臨時結論是Oracle 不支持這個,所以唯一可行的方法是 try-insert-catch-and-ignore-dup-key-error。真的只是想要幫助驗證或拒絕這個假設。

如果 2 個事務嘗試MERGE使用新值,則第二個事務將在ORA-00001第一個事務送出後得到一個。

第 1 節:

SQL> create table t1 (id number not null, constraint t1_pk primary key(id));

Table created.

SQL> merge into t1 using (select 1 as id from dual) s on (t1.id = s.id) 
    when not matched then insert (id) values (s.id);

1 row merged.

SQL>

會話 2(等待會話 1):

SQL> merge into t1 using (select 1 as id from dual) s on (t1.id = s.id) 
    when not matched then insert (id) values (s.id);

第 1 節:

SQL> commit;

Commit complete.

SQL>

第 2 節:

merge into t1 using (select 1 as id from dual) s on (t1.id = s.id)
when not matched then insert (id) values (s.id)
*
ERROR at line 1:
ORA-00001: unique constraint (BP.T1_PK) violated


SQL>

但是,Oracle 提供了IGNORE_ROW_ON_DUPKEY_INDEX提示,這將抑制第二個事務,ORA-00001並且第二個事務可以完成而不會出現錯誤,並且不會插入有問題的行。

第 1 節:

SQL> insert /*+ ignore_row_on_dupkey_index(t1,t1_pk) */ into t1 values (2);

1 row created.

SQL>

會話 2(等待會話 1):

SQL> insert /*+ ignore_row_on_dupkey_index(t1,t1_pk) */ into t1 values (2);

第 1 節:

SQL> commit;

Commit complete.

SQL>

第 2 節:

0 rows created.

SQL>

引用自:https://dba.stackexchange.com/questions/315926