【问题标题】:Getting integrity constraint error while loading the data加载数据时出现完整性约束错误
【发布时间】:2022-01-07 03:37:40
【问题描述】:
CREATE TABLE main_quest(
    e_id NUMBER(10) NOT NULL,
    CONSTRAINT pk_main_quest PRIMARY KEY ( e_id ));
    
insert into main_quest values(11);   
insert into main_quest values(12);
insert into main_quest values(13);
insert into main_quest values(14);
insert into main_quest values(15);
insert into main_quest values(16);
insert into main_quest values(17);
insert into main_quest values(18);

CREATE TABLE quest_staging (
    e_id            NUMBER(10),
    data_separator  VARCHAR2(100),
    CONSTRAINT pk_quest_staging PRIMARY KEY ( e_id )
);

insert into quest_staging values(11,'P');
insert into quest_staging values(12,'R');
insert into quest_staging values(13,'R P');
insert into quest_staging values(14,'C');
insert into quest_staging values(15,'C P');
insert into quest_staging values(20,'C P');

CREATE TABLE quest_ref (
    ref_id     NUMBER(10),
    ref_cat    VARCHAR2(50),
    ref_value  VARCHAR2(100),
    CONSTRAINT pk_quest_ref PRIMARY KEY ( ref_id )
);

insert into quest_ref values(1,'cat_1','PP');
insert into quest_ref values(2,'cat_1','R');
insert into quest_ref values(3,'cat_1','R P');
insert into quest_ref values(4,'cat_1','C');
insert into quest_ref values(5,'cat_1','C P');
insert into quest_ref values(6,'cat_1','I');
insert into quest_ref values(7,'cat_1','I P');
insert into quest_ref values(8,'cat_1','P');

CREATE SEQUENCE quest_main_sq;

CREATE TABLE quest_main (
    main_id number(10) DEFAULT quest_main_sq.NEXTVAL NOT NULL,
    e_id          NUMBER(10),
    ref_quest_id  NUMBER(10),
    CONSTRAINT pk_quest_main PRIMARY KEY ( main_id ),
    CONSTRAINT fk_quest_main FOREIGN KEY ( e_id )
        REFERENCES main_quest ( e_id )
);

我的尝试:

MERGE INTO quest_main m
           USING (SELECT n.e_id,
                         n.data_separator,
                         qr.ref_id separator
                    FROM quest_staging n
                         JOIN quest_ref qr
                            ON     qr.ref_value = n.data_separator
                               AND qr.ref_cat = 'cat_1'
                                    ) x
              ON (m.e_id = x.e_id)
      WHEN MATCHED
      THEN
         UPDATE SET  m.ref_quest_id = x.separator
      WHEN NOT MATCHED
      THEN
         INSERT     (main_id,
                     e_id,
                     ref_quest_id
                     )
             VALUES (quest_main_sq.nextval,
                     x.e_id,
                     x.separator
                     );

面临的问题:我想根据暂存表(即 quest_staging)和查找表(即 quest_ref)将记录插入到表主表(即 quest_main)中。如果暂存表中的 data_separator 列与查找表中的 ref_value 列匹配,则插入将发生在主表中。暂存表中的数据是 main_quest 表的子集。因此,如果在插入临时表中的记录时 main_quest 表中不存在 e_id,那么它应该跳过该记录并插入剩余的记录。但是在这里我遇到了类似的错误 错误报告 - ORA-02291: 违反完整性约束 (TAM.FK_QUEST_MAIN) - 未找到父键,因为 main_quest 表中不存在 e_id 20。但我需要处理它,它会跳过 e_id 20 并插入剩余的。

使用的工具:SQL Developer 版本:20.4.1.407.0006

预期输出:

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    如果我对您的理解正确,它只是修复它的 USING 中的 WHERE 子句(参见第 7 - 10 行):

    SQL> MERGE INTO quest_main m
      2       USING (SELECT n.e_id, n.data_separator, qr.ref_id separator
      3                FROM quest_staging n
      4                     JOIN quest_ref qr
      5                        ON     qr.ref_value = n.data_separator
      6                           AND qr.ref_cat = 'cat_1'
      7               WHERE EXISTS
      8                        (SELECT NULL
      9                           FROM main_quest m
     10                          WHERE m.e_id = n.e_id)) x
     11          ON (m.e_id = x.e_id)
     12  WHEN MATCHED
     13  THEN
     14     UPDATE SET m.ref_quest_id = x.separator
     15  WHEN NOT MATCHED
     16  THEN
     17     INSERT     (main_id, e_id, ref_quest_id)
     18         VALUES (quest_main_sq.NEXTVAL, x.e_id, x.separator);
    
    5 rows merged.
    

    结果:

    SQL> select * from quest_main;
    
       MAIN_ID       E_ID REF_QUEST_ID
    ---------- ---------- ------------
            24         12            2
            26         13            3
            28         14            4
            30         15            5
            32         11            8
    
    SQL>
    

    附:谢谢你的测试用例!

    【讨论】:

    • 谢谢。请告诉我为什么我们在这里使用 EXISTS
    • 避免父表中不存在的值。
    猜你喜欢
    • 1970-01-01
    • 2015-03-30
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多