为什么外键约束会在插入时出错?

时间:2017-03-27 15:37:54

标签: database oracle oracle11g oracle-sqldeveloper

如何在此表中插入列?任何帮助都会很棒。我希望能够在表productview中插入一列。

即使通过APEX对象浏览器插入也会出现此错误。但是我试图通过SQL命令

来做到这一点
error ORA-02291: integrity constraint (GCU.CUSVIS3ID3_FK) violated - parent key not found

我知道约束名称可能会有所不同,因为我有很多版本;对此可能有所不同。

CREATE TABLE  CUSTOMERS
   ( CUSTOMERID VARCHAR2(10000) NOT NULL, 
     NAME VARCHAR2(15) NOT NULL, 
     EMAIL VARCHAR2(50), 
     CUSTOMERTYPE VARCHAR2(23) DEFAULT  'BRONZE',
     PRIMARY KEY (CUSTOMERID),
CONSTRAINT CHECK_CUSTOMERTYPE CHECK(CUSTOMERTYPE IN ('SILVER', 'GOLD'))
   );
/
CREATE TABLE  CUSTOMERVisit
   ( CUSTOMERVISITID VARCHAR2 NOT NULL, 
     VisitDatetime TIMESTAMP, 
     VisitLength NUMBER DEFAULT 0,
     PRIMARY KEY (CUSTOMERVISITID),
CONSTRAINT "COUNTR_REG23324_FK" FOREIGN KEY ("CUSTOMERVISITID")
      REFERENCES  "CUSTOMERS" ("CUSTOMERID")
);

/
CREATE TABLE  PRODUCTVIEW
   ( ADDEDTOBASKET VARCHAR2,     
CONSTRAINT CHECK_ADDEDTOBASKET1 CHECK(ADDEDTOBASKET IN ('Y')),

CONSTRAINT "CUSID_FK" FOREIGN KEY ("ADDEDTOBASKET")
      REFERENCES  "CUSTOMERS" ("CUSTOMERID"),
CONSTRAINT "CUSVISID_FK" FOREIGN KEY ("ADDEDTOBASKET")
      REFERENCES  "CUSTOMERVISIT" ("CUSTOMERVISITID")

   );

1 个答案:

答案 0 :(得分:1)

您发布的外键......

CONSTRAINT "CUSID_FK" FOREIGN KEY ("ADDEDTOBASKET")
  REFERENCES  "CUSTOMERS" ("CUSTOMERID"),
CONSTRAINT "CUSVISID_FK" FOREIGN KEY ("ADDEDTOBASKET")
  REFERENCES  "CUSTOMERVISIT" ("CUSTOMERVISITID")

...强制执行PRODUCTVIEW表与CUSTOMERSCUSTOMERVISIT表之间的链接。上述代码的含义是PRODUCTVIEW.ADDEDTOBASKET CUSTOMERVISIT.CUSTOMERVISITID的值且<{1}}中必须存在CUSTOMERS.CUSTOMERID才能插入PRODUCTVIEW记录。

显然这是错误的,原因有两个:

  • 从建模的角度来看,它强制执行三个表之间的一对一关系,这是不寻常的
  • 数据类型不同。

您更有可能需要一个客户可以进行多次客户访问的模型,而一次客户访问可以有多个视图。在这种情况下:

  1. alter table customervisit drop constraint COUNTR_REG23324_FK;
  2. alter table productview drop constraint CUSID_FK;
  3. alter table productview drop constraint CUSVISID_FK;
  4. alter table customervisit add customerid varchar2(10000);
  5. alter table customervisit add constraint customervisit_customer_fk ( customerid) references customer (customerid);
  6. alter table productview add customervisitid varchar2(40);
  7. alter table productview add constraint productview_customervisit_fk ( customerid ) references customervisit (customervisitid);
  8. 顺便说一句,varchar2(10000)是我见过的主键最糟糕的定义。你应该获得某种奖励。

    无论如何,现在当你插入一条记录时,你会以CUSTOMER开头。要填充CUSTOMERVISIT,您需要将CUSTOMERS.CUSTOMERID的正确值传递给CUSTOMERVISIT.CUSTOMERID。同样要填充PRODUCTVIEW,您需要将CUSTOMERVISIT.CUSTOMERVISITID的正确值传递给PRODUCTVIEW.CUSTOMERVISITID

    像这样的东西。对于每个新客户:

    insert into customers3 (customerid, NAME, email, customertype)
     values (55, 'asdsa', 'asda@gmail.com', 'GOLD'); 
    

    每次客户拜访:

    insert into customervisit3 (customervisitid, customerid, 
         VisitDatetime )
      values (123 , 55, systimestamp);
    

    对于每个被浏览的产品:

    insert into productview3 (customervisitid, addedtobasket )
      values (123 , 'Y');
    

    如果您使用触发器使用序列值填充ID,则可以使用RETURNING子句捕获局部变量中的序列值。