Я считаю, что Postgres сохранит порядок серийных идентификаторов, когда insert . . . select
имеет order by
.Таким образом, вы можете делать то, что вы хотите, используя returning
и создавая таблицу сопоставления из старых и новых значений:
with s as (
insert into stores ( . . . )
select . . .
from stores
where store_id = @x
returning *
),
b as (
insert into books (store_id, . . . )
select s.store_id, . . .
from books b cross join
s
where b.store_id = @x
order by b.book_id
returning *
),
bb as (
select bold.book_id as old_book_id, bnew.book_id as new_book_id
from (select b.book_id,
row_number() over (order by book_id) as seqnum
from books b cross join
s
where b.store_id = @x
) bold join
(select b.*, row_number() over (order by book_id) as seqnum
from b
) bnew
on bnew.seqnum = bold.seqnum
)
insert into pages (book_id, . . .)
select bb.new_book_id, . . .
from pages p join
bb b
on p.book_id = bb.old_book_id;