oracle 如何避免重复的记录使用插入在PL/SQL块后运行块2-3次后,它开始给出约束错误?

qmb5sa22  于 2023-04-29  发布在  Oracle
关注(0)|答案(2)|浏览(110)

在运行该块超过2次之后,或者在该块内部,一个函数由于重复插入而给出了约束错误,如何避免重复插入到函数中?或查询,这样我就不需要手动写删除查询,单独需要添加一个查询,避免重复插入。
这是一个函数中块内的查询。

insert into igm.fcdrft(
    T, 
    G, 
    L
    STARTDATE,
    D ,
    TYPE , 
    F,  
    Q ,
    M,
    DAYS
    )
select f.T, 
    f.G, 
    f.L,
    u.startDate,
    f.D ,
    f.TYPE ,
    f.F,
    f.Q,
    f.M,    
    u.DAYS
from igm.TEMP  f 
LEFT join igm.part u  
on u.ACT_STARTD=f.startdate
where f.type in ('2','3') 
and u.startdate between '01-09-2023' and '13-01-2025';
lfapxunr

lfapxunr1#

主键是什么?

Alter table  igm.fcdrft add constraint fcdrft_pk primary key(...)

然后

insert into igm.fcdrft (...)
select ... log errors into igm.fcdrft_err reject limit nolimit

参见https://livesql.oracle.com/apex/livesql/file/content_JNEICX6W0LNOA88CQIXO9A22A.html
不过,如果insert select没有日志错误,并确保select不会返回违反该表主键的行,性能会更好。你也可以insert select ... where not exists (...),以确保你不会违反PK。或者,您可以使用merge而不是insert,具体取决于业务需求。

piok6c0g

piok6c0g2#

您可以使用not exists来避免在igm.fcdrft中插入已经存在的记录:

insert into igm.fcdrft(
    T, 
    G, 
    L
    STARTDATE,
    D ,
    TYPE , 
    F,  
    Q ,
    M,
    DAYS
    )
select f.T, 
    f.G, 
    f.L,
    u.startDate,
    f.D ,
    f.TYPE ,
    f.F,
    f.Q,
    f.M,    
    u.DAYS
from igm.TEMP  f 
LEFT join igm.part u  
on u.ACT_STARTD=f.startdate
where f.type in ('2','3') 
and u.startdate between '01-09-2023' and '13-01-2025'
and not exists
(
    select null from igm.fcdrft where igm.fcdrft.T=f.T and igm.fcdrft.G=f.G and igm.fcdrft.STARTDATE=u.startDate, igm.fcdrft.Q=f.Q and igm.fcdrft.M=f.M
)

相关问题