通过完整性约束异常处理插入主表

时间:2015-04-14 19:06:22

标签: sql plsql oracle11g

DB:Oracle 11gR2 操作系统:Windows 7客户端

您好, 我有一个主表和一个详细信息表如下:

create table country (id     NUMBER not null,      code    VARCHAR2(2) not null, creation_date    date, constraint pk_country_id primary key (code));
create table country_detail (code    VARCHAR2(2), description VARCHAR2(100),  creation_date    date, modify_date    date, constraint fk_country_id foreign key (code) references country(code));

insert into country values(1, 'US', sysdate);
insert into country values(2, 'CA', sysdate); -- missing on DB1
insert into country values(3, 'MX', sysdate);
insert into country values(4, 'CH', sysdate);
insert into country values(5, 'IN', sysdate); -- missing on DB2
insert into country values(6, 'JP', sysdate);

insert into country_detail values('US', 'United States of Ameica', sysdate, sysdate);
insert into country_detail values('CA', 'Canada', sysdate, sysdate); -- missing on DB1
insert into country_detail values('MX', 'Mexico', sysdate, sysdate);
insert into country_detail values('CH', 'Peoples republic of china', sysdate, sysdate);
insert into country_detail values('IN', 'Republic of India', sysdate, sysdate); -- missing on DB2
insert into country_detail values('JP', 'Japan', sysdate, sysdate);

现在国家/地区表存在于2个数据库中,但数据不一样,例如在DB1上,让我们说“CA'缺少并且在DB2' IN'不见了。以上6个代码可以是可以驻留在这些表中的最大值。

现在我想通过(SQL或PL / SQL)脚本在country_detail表中插入这6条记录,这样它就不会在任何数据库上失败。即在DB1尝试插入' CA' (或者在DB2上插入' IN')它不应该因为违反完整性约束而失败 - 未找到父密钥"。而是当它看到它应该在异常(对于PL / SQL或某种类型的SQL语句,如合并)部分中应该处理的错误,首先在country表中插入数据,然后在country_detail表中插入相应的记录。

任务是完全同步2个数据库上的数据(即两个环境都应该在两个表中都有6个记录)。

有没有办法可以通过像Merge这样的SQL语句来完成。如果它是一个SQL语句,我们可以逐个插入每个国家/地区。

如果不能在单个SQL中完成,那么如何在PL / SQL中实现它(什么样的错误处理将实现最终结果)。注意,在PL / SQL中,我将只处理1个块中的所有数据(即只有1个{begin ... exception ... end;}块)。如何做到这一点?

由于

1 个答案:

答案 0 :(得分:0)

您要求的内容很简单:

merge into country c
using(
    select  ID, code, Created
    from(
        select  1 ID, 'US' Code, sysdate Created from dual union all
        select  2, 'CA', sysdate from dual union all
        select  3, 'MX', sysdate from dual union all
        select  4, 'CH', sysdate from dual union all
        select  5, 'IN', sysdate from dual union all
        select  6, 'JP', sysdate from dual
    ) ) v
on( c.Code = v.code )
when not matched then
    insert( id, code, Creation_Date )
    values( v.id, v.code, v.Created );

只需根据需要更改其他表的内联视图。

但请允许我提问:Country表的ID字段的用途是什么?它不是主键,是Code字段(我同意这是更好的选择)。它本来可能是PK,但是当Code将自己表现为两者中的更好时,它就会改变。如果它是一个残余的领域,摆脱它。