Удалить записи, на которые ссылаются другие записи в разных таблицах - PullRequest
1 голос
/ 19 февраля 2020

У меня есть следующее требование:

Мне нужно удалить записи из одной таблицы на основе данного идентификатора, теперь на эту таблицу ссылается другая таблица, а на другую таблицу ссылается еще одна таблица, и эта последняя На таблицу также ссылается другая таблица, поэтому у меня есть такая цепочка:

table_1 <- table_2 <- table_3 <- table_4

Я не настолько опытен с SQL, поэтому мое решение предполагает использование подзапросов для выполнения этой задачи. .

У меня есть что-то вроде этого:

DELETE FROM table_4
     WHERE pk_of_table_3 IN 
               (SELECT id
                FROM table_3
                WHERE pk_of_table_2 IN 
                          (SELECT id FROM table 2 WHERE pk_of_table_1 = ?
                          )
               )

Так что это очистит записи из таблицы_4, которые ссылаются на целевые записи в таблице_3.

Для таблицы_3 я бы сделал что-то вроде:

DELETE FROM table_3
    WHERE pk_of_table_2 IN 
              (SELECT id FROM table_2 WHERE pk_of_table_1 = ?)

Теперь я перехожу к таблице_2:

DELETE FROM table_2 WHERE pk_of_table_1 = 5;

Таким образом, в итоге у меня появляется возможность удалить необходимые записи из таблицы_1, поскольку она ничем не ограничена.

Я хотел спросить, кажется ли это жизнеспособным решением и есть ли лучшие способы сделать это?

1 Ответ

3 голосов
/ 19 февраля 2020

Сделайте это с помощью общего табличного выражения, которое объединяет операторы DELETE:

with delete_t1 as (
  delete from table_1
  where pk = 42
  returning pk
), delete_t2 as (
  delete from table_2
  where pk_of_table_1 in (select pk from delete_t1)
  returning pk
), delete_t3 as (
  delete from table_3
  where pk_of_table_2 in (select pk from delete_t2)
  returning pk
)
delete from table_4
where pk_of_table_3 in (select pk from delete_t3);

Если вы всегда так делаете, рассмотрите возможность определения ограничений внешнего ключа как on delete cascade, тогда вы только нужно удалить из таблицы_1, а Postgres позаботится об остальном.

...