Как удалить строки из разных таблиц? - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть родительская таблица с коллекцией идентификаторов, как перенести эту коллекцию в другие таблицы в блоке ГДЕ для удаления?
пример:

select id from table_a <- it's collection of ids.
delete from table_b where table_b.ad_id in (COLLECTION_OF_IDS_FROM_PREVIOS_SQL_SCRIPT)
delete from table_c where table_c.ad_id in (COLLECTION_OF_IDS_FROM_PREVIOS_SQL_SCRIPT)
...

нет возможности каскадного удаления

Я нахожу решение

delete from table_b where table_b.ad_id in (select id from table_a)
...

Как оптимизировать это решение?

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

После краткого размышления я хочу превратить свой предыдущий ответ в «ответ».

Подобная ситуация - в любой базе данных SQL - идеальный случай для SQL «транзакций». Транзакция - это атоми c единица работы. Сначала вы BEGIN TRANSACTION, затем вы вводите одну или несколько SQL команд. Когда вы заканчиваете sh, COMMIT. Или, если что-то пойдет не так, ROLLBACK.

(используйте try..except logi c в своих программах, чтобы гарантировать, что ROLLBACK произойдет, если возникнет исключение.)

Другие пользователи системы базы данных либо увидят, что "все внесенных вами изменений произошли, мгновенно", когда вы COMMIT, либо что "Ни один из них не сделал." Другие пользователи не будут видеть базу данных в «промежуточном состоянии», даже если вы это сделаете.

0 голосов
/ 15 апреля 2020

Вы можете сделать это, используя данные, модифицирующие CTE :

with id_list as (
   select id 
   from table_a 
   where ...
), delete_b as (
   delete from table_b 
   where table_b.ad_id in (select * from id_list)
)
delete from table_c 
where table_c.ad_id in (select * from id_list);

Это также может быть использовано для удаления строк из иерархии таблиц, которые связаны с внешними ключами (по сути, «ручное» каскадное удаление).

with remove_root as (
   delete from root_table
   where ....
   returning pk_column
), delete_child_1 as (
  delete from child_one
  where root_id in (select * from remove_root)
  returning pk_column
), delete_child_2 as (
  delete from child_one
  where root_id in (select * from remove_root)
)
delete from grand_child
where child_one_id in (select * from delete_child_1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...