使用从insert返回的id,用于使用外键进行记录插入

时间:2015-10-29 12:41:14

标签: sql postgresql

我有一张桌子

monster(id serial, name varchar, primary key(id))

我有另一张桌子

ranged_monster(id_monster integer, distance integer, foreign key(id_monster) references monster)

我想插入两个远程怪物:一个叫做'弓箭手精灵',射程距离 10 ,另一个称为'龙,范围攻击距离 50 。我怎么能在一条指令中做到这一点?

到目前为止,我试过这个:

最糟糕的方式

insert into monster(name) values ('archer goblin'), ('dragon');

insert into ranged_monster(distance) values (10) where name='archer goblin';

insert into ranged_monster(distance) values (50) where name='dragon';

这很糟糕,因为名称列允许重复,并且检索到的记录可能不止一个......还要写两次怪物的名字似乎不是一个好习惯。

插入...返回

如果表ranged_monster只有id_monster的列(外键),那么我可以使用此解决方案:

with the_ids as (
    insert into monster(name) 
    values ('archer goblin'), ('dragon') 
    returning id
) 
insert into ranged_monster(id_monster) 
    select * from the_ids;

然而它不起作用,因为ranged_monster也有列distance。这样做,将在没有distance的情况下插入怪物的ID。

可能的解决方案

创建一个包含距离的时态表,然后将此时态表顺序与insert into ... returning的{​​{1}}组合,然后将这些组合记录插入the_ids表。

如何按照https://stackoverflow.com/questions/31171253/sql-combine-two-tables中的要求组合两个表格? (它被标记为重复,链接到此What is the difference between JOIN and UNION?,但该问题与另一个问题无关。)

1 个答案:

答案 0 :(得分:1)

with s(name, distance) as (
    values ('archer goblin', 10), ('dragon', 50)
), the_ids as (
    insert into monster(name) 
    select name
    from s
    returning id, name
)
insert into ranged_monster (id_monster, distance)
select id, distance
from
    s
    inner join
    the_ids using (name)