0

好的,所以我目前正在为大学作业开发 Oracle 11G 速成版。我遇到了一个关于如何在以下父表中自动递增和更新的问题。所以我有一个地址表,然后是一个城市表。这里是地址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 并自动将其正确放入父表中?

4

2 回答 2

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;

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

于 2019-03-15T14:53:03.890 回答
0

您对表格及其关系有误解。

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

一种可能的数据模型:

国家(国家 ID、国家名称、国家代码)
  pk country_id

县(county_id,county_name)
  pk County_id
  fk country_id -> 国家

城市(city_id、city_name、邮政编码、county_id)
  pk city_id
  fk County_id -> 县

街道(street_id,街道名称,city_id)
  pk street_id
  fk city_id -> 城市

地址(address_id、street_id、door_number
  pk address_id
  fk street_id -> 街道

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

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

于 2019-03-14T19:29:03.320 回答