cwa*_*ole 42 sql oracle oracle-sqldeveloper
我需要能够运行Oracle查询,该查询将插入多个行,但它还会检查是否存在主键,如果存在,则会跳过该插入.就像是:
INSERT ALL
IF NOT EXISTS( SELECT 1 WHERE fo.primary_key='bar' )
(
INSERT INTO
schema.myFoo fo ( primary_key, value1, value2 )
VALUES
('bar','baz','bat')
),
IF NOT EXISTS( SELECT 1 WHERE fo.primary_key='bar1' )
(
INSERT INTO
schema.myFoo fo ( primary_key, value1, value2 )
VALUES
('bar1','baz1','bat1')
)
SELECT * FROM schema.myFoo;
Run Code Online (Sandbox Code Playgroud)
Oracle完全可以实现这一点吗?
如果您可以告诉我如何在PostgreSQL或MySQL中执行此操作,可以获得奖励积分.
Mic*_*uff 37
迟到了,但......
使用oracle 11.2.0.1,有一个语义提示可以执行此操作:IGNORE_ROW_ON_DUPKEY_INDEX
例:
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(customer_orders,pk_customer_orders) */
into customer_orders
(order_id, customer, product)
values ( 1234, 9876, 'K598')
;
Run Code Online (Sandbox Code Playgroud)
更新:尽管此提示有效(如果拼写正确),但有更好的方法不需要Oracle 11R2:
第一种方法 - 直接翻译上述语义提示:
begin
insert into customer_orders
(order_id, customer, product)
values ( 1234, 9876, 'K698')
;
commit;
exception
when DUP_VAL_ON_INDEX
then ROLLBACK;
end;
Run Code Online (Sandbox Code Playgroud)
其次的形式给出,一个很多比上面的时候有很多争论的双方提示更快:
begin
select count (*)
into l_is_matching_row
from customer_orders
where order_id = 1234
;
if (l_is_matching_row = 0)
then
insert into customer_orders
(order_id, customer, product)
values ( 1234, 9876, 'K698')
;
commit;
end if;
exception
when DUP_VAL_ON_INDEX
then ROLLBACK;
end;
Run Code Online (Sandbox Code Playgroud)
eri*_*len 24
该声明称为MERGE.抬起头来,我太懒了.
但要注意,MERGE不是原子的,这可能会导致以下影响(谢谢,Marius):
SESS1:
create table t1 (pk int primary key, i int);
create table t11 (pk int primary key, i int);
insert into t1 values(1, 1);
insert into t11 values(2, 21);
insert into t11 values(3, 31);
commit;
Run Code Online (Sandbox Code Playgroud)
SESS2: insert into t1 values(2, 2);
SESS1:
MERGE INTO t1 d
USING t11 s ON (d.pk = s.pk)
WHEN NOT MATCHED THEN INSERT (d.pk, d.i) VALUES (s.pk, s.i);
Run Code Online (Sandbox Code Playgroud)
SESS2: commit;
SESS1: ORA-00001
小智 18
仅当要插入的项目尚未存在时才会插入.
作用相同:
if not exists (...) insert ...
Run Code Online (Sandbox Code Playgroud)
在T-SQL中
insert into destination (DESTINATIONABBREV)
select 'xyz' from dual
left outer join destination d on d.destinationabbrev = 'xyz'
where d.destinationid is null;
Run Code Online (Sandbox Code Playgroud)
可能不漂亮,但它很方便:)
Ray*_*hiu 11
我们可以将DUAL和NOT EXISTS结合起来存档您的要求:
INSERT INTO schema.myFoo (
primary_key, value1, value2
)
SELECT
'bar', 'baz', 'bat'
FROM DUAL
WHERE NOT EXISTS (
SELECT 1
FROM schema.myFoo
WHERE primary_key = 'bar'
);
Run Code Online (Sandbox Code Playgroud)
小智 10
如果你不想从其他表合并,而是插入新数据......我想出了这个.有没有更好的方法来做到这一点?
MERGE INTO TABLE1 a
USING DUAL
ON (a.C1_pk= 6)
WHEN NOT MATCHED THEN
INSERT(C1_pk, C2,C3,C4)
VALUES (6, 1,0,1);
Run Code Online (Sandbox Code Playgroud)
它代码在客户端,然后你有许多访问服务器,以消除它.
将所有数据插入到临时表中,表示T与myFoo具有相同的结构
然后
insert myFoo
select *
from t
where t.primary_key not in ( select primary_key from myFoo)
Run Code Online (Sandbox Code Playgroud)
这应该适用于其他数据库 - 我在Sybase上完成了这项工作
如果您通过线路复制了所有数据,那么插入新数据的次数并不是最好的.