Глубокая копия сущности и отношений с использованием SQL - PullRequest
0 голосов
/ 03 января 2019

У меня три таблицы

Store
  Book
    Page

Магазин - это книга «один ко многим», книга - это книга «один ко многим», и у всех них установлены внешние ключи. Я хочу создать копии магазина (и, следовательно, книг и страниц), используя SQL-запрос. Я пытался использовать CTE, но у меня проблемы с поддержанием отношений между сущностями.

Я не пытаюсь создать новую таблицу, просто создаю дубликат определенной строки Store (и ее взаимосвязей), идентификаторы в таблицах являются последовательными.

Итак, копия

Store 1
  Book 1 (store_id: 1)
    Page 1 (book_id: 1)
    Page 2 (book_id: 1)

будет

Store 2
  Book 2 (store_id: 2)
    Page 3 (book_id: 2)
    Page 4 (book_id: 2)

1 Ответ

0 голосов
/ 03 января 2019

Я считаю, что 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;
...