UPSERT操作在表中更新或插入一行,这取决于表中是否已经有与数据匹配的行:
if table t has a row exists that has key X:
update t set mystuff... where mykey=X
else
insert into t mystuff...
既然Oracle没有特定的UPSERT语句,那么最好的方法是什么呢?
UPSERT操作在表中更新或插入一行,这取决于表中是否已经有与数据匹配的行:
if table t has a row exists that has key X:
update t set mystuff... where mykey=X
else
insert into t mystuff...
既然Oracle没有特定的UPSERT语句,那么最好的方法是什么呢?
当前回答
从http://www.praetoriate.com/oracle_tips_upserts.htm:
在Oracle9i中,UPSERT可以在一条语句中完成这个任务:
INSERT
FIRST WHEN
credit_limit >=100000
THEN INTO
rich_customers
VALUES(cust_id,cust_credit_limit)
INTO customers
ELSE
INTO customers SELECT * FROM new_customers;
其他回答
MERGE(“老式的方式”)的替代方案:
begin
insert into t (mykey, mystuff)
values ('X', 123);
exception
when dup_val_on_index then
update t
set mystuff = 123
where mykey = 'X';
end;
MERGE语句合并两个表之间的数据。使用双 允许我们使用此命令。请注意,这没有针对并发访问进行保护。
create or replace
procedure ups(xa number)
as
begin
merge into mergetest m using dual on (a = xa)
when not matched then insert (a,b) values (xa,1)
when matched then update set b = b+1;
end ups;
/
drop table mergetest;
create table mergetest(a number, b number);
call ups(10);
call ups(10);
call ups(20);
select * from mergetest;
A B
---------------------- ----------------------
10 2
20 1
从http://www.praetoriate.com/oracle_tips_upserts.htm:
在Oracle9i中,UPSERT可以在一条语句中完成这个任务:
INSERT
FIRST WHEN
credit_limit >=100000
THEN INTO
rich_customers
VALUES(cust_id,cust_credit_limit)
INTO customers
ELSE
INTO customers SELECT * FROM new_customers;
没有异常检查的另一种方法:
UPDATE tablename
SET val1 = in_val1,
val2 = in_val2
WHERE val3 = in_val3;
IF ( sql%rowcount = 0 )
THEN
INSERT INTO tablename
VALUES (in_val1, in_val2, in_val3);
END IF;
上面在PL/SQL中的双重示例很棒,因为我想做一些类似的事情,但我想在客户端……所以这里是SQL我用来发送一个类似的语句直接从一些c#
MERGE INTO Employee USING dual ON ( "id"=2097153 )
WHEN MATCHED THEN UPDATE SET "last"="smith" , "name"="john"
WHEN NOT MATCHED THEN INSERT ("id","last","name")
VALUES ( 2097153,"smith", "john" )
然而,从c#的角度来看,这比执行更新和查看受影响的行是否为0以及如果为0则执行插入要慢。