【问题标题】:Basic primary key / foreign key with constraint, sequence, trigger具有约束、序列、触发器的基本主键/外键
【发布时间】:2013-04-27 23:46:50
【问题描述】:

Oracle 11g 中的学习者。我在将一些行插入由主/外键关系链接的两个表中时遇到问题。

基本上我创建了一个从 1000 开始并以 1 递增的序列。

然后创建一个带有 ST_ID 列的“STORE”表

ST_ID 列通过 TRIGGER 链接到 SEQUENCE。

然后我有一个“EMPLOYEE”表,其中有一个 EST_ID 字段,该字段是 STORE 表中 ST_ID 列的外键。

但是,当我尝试插入行时,我最初收到一条错误消息,指出 EST_ID 不能为空。所以我为 EST_ID 创建了一个序列和触发器,现在我收到一条错误消息,指出违反了外键约束。

我认为这可能是错误的做法。我真的希望 E_ID 和 EST_ID 相同吗?我该如何实现?用某种触发器?

实际代码:

 CREATE SEQUENCE   "STORSEQ"  MINVALUE 1000 MAXVALUE 9999 INCREMENT BY 1 START WITH     1000     NOCACHE  NOORDER  

NOCYCLE ;

CREATE TABLE  "STORE" 
   (    "ST_ID" CHAR(4) NOT NULL ENABLE, 
    "STADDR_ID" CHAR(4) NOT NULL ENABLE, 
     CONSTRAINT "STORE_PK" PRIMARY KEY ("ST_ID") ENABLE
   ) ;

CREATE TABLE  "EMPLOYEE" 
   (    "E_ID" CHAR(8) NOT NULL ENABLE, 
    "EF_NAME" VARCHAR2(20) NOT NULL ENABLE, 
    "EL_NAME" VARCHAR2(20) NOT NULL ENABLE, 
    "EST_ID" CHAR(4) NOT NULL ENABLE, 
     CONSTRAINT "EMPLOYEE_PK" PRIMARY KEY ("E_ID") ENABLE
   ) ;

alter table "EMPLOYEE" add CONSTRAINT "EMPLOYEE_CON" foreign key ("EST_ID") references 

"STORE" ("ST_ID")
/

CREATE OR REPLACE TRIGGER  "BI_STORE" 
  before insert on "STORE"               
   for each row  
begin   
  if :NEW."ST_ID" is null then 
    select "STORSEQ".nextval into :NEW."ST_ID" from dual; 
  end if; 
end; 

/

目前我的 INSERT 代码如下所示:

    INSERT INTO STORE
    (ST_ID, STADDR_ID)
    VALUES
    (DEFAULT, DEFAULT);

    INSERT INTO EMPLOYEE
    (EF_NAME, EL_NAME)
    VALUES
    ('James', 'Smith');

【问题讨论】:

  • 当您插入员工时,您是否传递了 EST_ID 的值?
  • 不,我不是。只是其他列的值。我认为代码可能知道自动在 EST_ID 中插入与 ST_ID 相同的值,但我想我完全错了?
  • 是的,它不会自动为您插入值,您需要传递该值。您是否在单个事务中在两个表中插入行?
  • 但是如果 ST_ID 是由 SEQUENCE 和 TRIGGER 自动插入的,我如何传递任何值?我是否需要另一个触发器来表示“将与 ST_ID 相同的值放入 EST_ID 中?” (感谢您的帮助 - 非常感谢)
  • 你是如何执行你的插入语句的?他们是在同一个程序中一个接一个地执行吗?

标签: sql oracle11g


【解决方案1】:

当您尝试将数据插入到具有外键引用的表中时,它不会自动获取 id 的值,您需要传递该值。

你可以这样做:

declare 
v_store_id integer;
begin
  INSERT INTO STORE (ST_ID, STADDR_ID) VALUES (DEFAULT, DEFAULT)
  RETURNING ST_ID INTO v_Store_id; 

  INSERT INTO EMPLOYEE (EF_NAME, EL_NAME, EST_ID) 
   VALUES ('James', 'Smith', v_store_id);
end;

您也可以在不使用触发器的情况下将 id 插入到商店 id 表中

declare 
v_store_id integer;
begin
  INSERT INTO STORE (ST_ID, STADDR_ID) VALUES ("STORSEQ".nextval, DEFAULT)
  RETURNING ST_ID INTO v_Store_id; 

  INSERT INTO EMPLOYEE (EF_NAME, EL_NAME, EST_ID) 
  VALUES ('James', 'Smith', v_store_id);
end

【讨论】:

  • LEGEND - 绝妙的答案。谢谢一百万!
猜你喜欢
  • 1970-01-01
  • 2016-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
相关资源
最近更新 更多