oracle sql:如果存在则更新,否则插入

Aks*_*Aks 33 sql oracle

可能重复:
Oracle:如何UPSERT(更新或插入表?)

嗨,

我有一个表,如果记录已经存在,则必须修改该记录,否则必须插入新记录.Oracle sql不接受IF EXISTS,否则我会做一个if - update - else - insert查询.我看过MERGE但它只适用于多个表.我该怎么办?

Ton*_*ews 63

MERGE不需要"多个表",但确实需要查询作为源.这样的事情应该有效:

MERGE INTO mytable d
USING (SELECT 1 id, 'x' name from dual) s
ON (d.id = s.id)
WHEN MATCHED THEN UPDATE SET d.name = s.name
WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name);
Run Code Online (Sandbox Code Playgroud)

或者你可以在PL/SQL中执行此操作:

BEGIN
  INSERT INTO mytable (id, name) VALUES (1, 'x');
EXCEPTION
  WHEN DUP_VAL_ON_INDEX THEN
    UPDATE mytable
    SET    name = 'x'
    WHERE id = 1;
END;
Run Code Online (Sandbox Code Playgroud)

  • +1我不知道`MERGE`指令,但对于异常`DUP_VAL_ON_INDEX`处理,这绝对是一个不错的解决方案,知道Oracle异常处理经常用于这种行为!=) (2认同)
  • +1;应该指出的是,替代解决方案的效率通常要低得多。 (2认同)

Ada*_*sch 8

merge into MY_TABLE tgt
using (select [expressions]
         from dual ) src
   on (src.key_condition = tgt.key_condition)
when matched then 
     update tgt
        set tgt.column1 = src.column1 [,...]
when not matched then 
     insert into tgt
        ([list of columns])
     values
        (src.column1 [,...]);
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以使用SQL%ROWCOUNTOracle变量:

UPDATE table1
  SET field2 = value2, 
      field3 = value3 
WHERE field1 = value1; 

IF (SQL%ROWCOUNT = 0) THEN 

  INSERT INTO table (field1, field2, field3)
  VALUES (value1, value2, value3);

END IF; 
Run Code Online (Sandbox Code Playgroud)

仅确定您的主键(即field1)是否具有值,然后相应地执行插入或更新会更容易。也就是说,如果您将所述值用作存储过程的参数。

  • 如果您有多个会话同时编写,则可能会遇到以下情况:“更新”触及零行,因此您假设没有行并且需要执行“插入”操作,但与此同时有人进行了“插入”操作`因此,您的`insert`会因唯一的约束冲突而失败。这就是为什么先执行“插入”(并捕获唯一的约束违例)然后执行“更新”,而不是相反的原因。 (9认同)

Pab*_*ruz -1

如果您想在Oracle中使用UPSERT/MERGE命令,请参考这个问题。否则,只需先在客户端解决问题count(1),然后再决定是插入还是更新。