使用从 insert into 返回的 id,用于使用外键插入记录
Posted
技术标签:
【中文标题】使用从 insert into 返回的 id,用于使用外键插入记录【英文标题】:using the ids returned from insert into, for record insertion with foreign key 【发布时间】:2016-01-29 14:43:43 【问题描述】:我有一张桌子
monster(id serial, name varchar, primary key(id))
我还有一张桌子
ranged_monster(id_monster integer, distance integer, foreign key(id_monster) references monster)
我要插入两个远程怪物:一个叫'archer goblin',远程攻击距离10,另一个叫'dragon ' 范围攻击距离为 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
的the_ids
顺序组合,然后将组合后的记录插入到ranged_monster
表中。
如何按照https://***.com/questions/31171253/sql-combine-two-tables 的要求合并两个表格? (它被标记为重复,链接到此 What is the difference between JOIN and UNION? ,但该问题与另一个问题无关。)
【问题讨论】:
是否有特定原因需要返回每个插入的 ID? 我想知道插入的id,因为我需要用这个id在ranged_monster
的表中插入一条记录。
看看这个***.com/questions/2944297/…它可能会帮助你
是的,这是一个非常有用的问题...谢谢 :D 我从那里提取了第二种可能的解决方案...我可以检索插入的 ID,但我不能将它们与附加的我需要插入的数据:(
我可以假设您的插入是从外部应用程序获取数据吗?您可以使用带有currval()
函数的事务来单独插入每个“项目”,并在应用程序中使用循环来处理多个插入
【参考方案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)
【讨论】:
你是个天才!有用!!谢谢!!我只是想指出,使用名称将 the_ids 与 s 内部连接是绝对必要的,因为 s 没有 ids。此外,这个内部连接只会在 s 变量中搜索名称,从而防止从怪物表中检索重复的 id。 @Bengalaa BTW 为什么name
不是monster
表的主键?该表中还有其他列吗?以上是关于使用从 insert into 返回的 id,用于使用外键插入记录的主要内容,如果未能解决你的问题,请参考以下文章
用于 SQL Server 的 insert ignore into 的替代方案
VB 操作sqlserver执行insert into语句,如何返回自增的ID值?
C#程序oracle数据库只能够 Insert into怎样得到返回该条纪录的主键的值