自动增量FK如何更新?

时间:2019-03-14 18:53:23

标签: sql oracle foreign-keys database-sequence

好,所以我目前正在为大学分配Oracle 11G Express Edition。我在以下父表中遇到了有关如何自动递增和更新的问题。所以我有一个地址表,然后有一个城市表。这是地址SQL代码

create table address(
addressid int primary key,
cityid int,
countyid int,
streetnameid int,
postcodeid int,
doornumid int,
natid int,
foreign key (doornumid) references doornum,
foreign key (postcodeid) references postcode,
foreign key (streetnameid) references streetname,
foreign key (countyid) references county,
foreign key (cityid) references city,
foreign key (natid) references nat);

如您所见,我将城市表引用为外键,这是下面的城市SQL表代码:

create table city(
cityid int primary key,
city varchar(45));

城市代码在插入东西时使用序列自动递增:

create SEQUENCE seq_cityID
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 11;

所以我简单地通过一个城市ID自动增加所有输入:

INSERT INTO city (cityid, city)
values(seq_cityID.nextval, Oxford);
INSERT INTO city (cityid, city)
values(seq_cityID.nextval, Oxford);

但是我的问题是当我在其父表中引用它时,例如地址表中如何引用该数据行的ID,并确保无需手动输入即可提取正确的ID?

INSERT INTO address (addressid, cityid, countyid, streetnameid, postcodeid, doornumid, natid)
values(seq_addressID.nextval, seq_cityID.nextval, seq_countyID.nextval, seq_streetnameID.nextval, seq_postcodeID.nextval, seq_doornumID.nextval, seq_natID.nextval);
INSERT INTO address (addressid, cityid, countyid, streetnameid, postcodeid, doornumid, natid)
values(seq_addressID.nextval, seq_cityID.nextval, seq_countyID.nextval, seq_streetnameID.nextval, seq_postcodeID.nextval, seq_doornumID.nextval, seq_natID.nextval);

这是简单的插入地址,当前仅引用nextval,但我不认为它将从该ID中提取该行数据。如何有效地从子表中提取该ID并将其正确正确地自动放入父表中?

2 个答案:

答案 0 :(得分:0)

您对表及其关系有误解。

您的数据模型有一个用于所有城市名称的表,一个用于所有街道名称的表,一个用于所有门号的表,等等。但是为什么要有一个包含门号的表?它告诉你什么?门号本身不是一个实体。他们属于一条街。街道属于城市。找到所有居住在12号或大街上的人是没有意义的。

一种可能的数据模型:

country (country_id, country_name, country_code)
  pk country_id

county (county_id, county_name)
  pk county_id
  fk country_id -> country

city (city_id, city_name, postcode, county_id)
  pk city_id
  fk county_id -> county

street (street_id, street name, city_id)
  pk street_id
  fk city_id -> city

address (address_id, street_id, door_number
  pk address_id
  fk street_id -> street

使用此数据模型,我们可以检查一致性。如果要输入意大利牛津的111 Millstreet地址,数据库将告诉我们意大利没有牛津。我们还可以轻松找到同一条街上的地址(而不是“在Main Street上有500万个地址,而是在俄亥俄州Main Street上有800个地址”。

如果要插入新地址,请先查询国家/地区,然后查询县,等等,直到获得街道ID。

答案 1 :(得分:0)

使用原始表格:

declare
  v_countyid     integer;
  v_cityid       integer;
  v_streetnameid integer;
begin
  insert into city (city_name) values ('Saint Petersburg') returning cityid into v_city_d;
  insert into streetname (street_name) values ('Park Drive') returning streetnameid into v_streetnameid;
  ...

  insert into address (cityid, streetnameid, ...) values (v_cityid, v_streetnameid, ...);

  commit;
end;

但是,表中将有重复的城市,街道名称等。因此,我们宁愿:

declare
  v_countyid     integer;
  v_cityid       integer;
  v_streetnameid integer;
begin
  select cityid into v_cityid from city where city_name = 'Saint Petersburg';

  if cityid is null then
    insert into city (city_name) values ('Saint Petersburg') returning cityid into v_city_d;
  end if;

  select streetnameid into v_streetnameid from streetname where street_name = 'Park Drive';

  if v_streetnameid is null then
    insert into streetname (street_name) values ('Park Drive') returning streetnameid into v_streetnameid;
  end if;
  ...

  insert into address (cityid, streetnameid, ...) values (v_cityid, v_streetnameid, ...);

  commit;
end;

但是正如我在其他答案中所提到的。无论如何,这种数据模型没有多大意义。