PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Postgresql изтрива няколко реда от множество таблици

Организирането на правилни каскадни изтривания е мъдро и обикновено е правилното решение за това. За някои специални случаи има друго решение за това, което може да бъде подходящо.

Ако трябва да извършите множество изтривания въз основа на общ набор от данни, можете да използвате Общи таблични изрази (CTE) .

Трудно е да се измисли прост пример, тъй като основният случай на употреба за това може да бъде покрит от каскадни изтривания.

За примера ще изтрием всички елементи в таблица A, чиято стойност е в набора от стойности, които изтриваме от таблица B. Обикновено това са ключове, но когато не са, тогава не може да се използва каскадно изтриване .

За да решите това, използвате CTE

WITH Bdeletes AS (
    DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)

Този пример е умишлено прост, защото целта ми не е да споря за съпоставяне на ключове и т.н., а да покажа как две или повече изтривания могат да бъдат извършени от споделен набор от данни. Това също може да бъде много по-сложно, включително команди за актуализиране и т.н.

Ето един по-сложен пример (от личната база данни на Дарт Вейдър). В този случай имаме таблица, която препраща към адресна таблица. Трябва да изтрием адреси от таблицата с адреси, ако са в неговия списък с планети, които е унищожил. Искаме да използваме тази информация, за да изтрием от таблицата с хора, но само ако са били на планета (или в неговия списък за убийства на трофеи)

with AddressesToDelete as (
    select AddressId from Addresses a 
    join PlanetsDestroyed pd on pd.PlanetName = a.PlanetName
),
PeopleDeleted as (
    delete from People 
    where AddressId in (select * from AddressesToDelete)
    and OffPlanet = false 
    and TrophyKill = false
    returning Id
),
PeopleMissed as (
    update People 
    set AddressId=null, dead=(OffPlanet=false)
    where AddressId in (select * from AddressesToDelete)
    returning id
)
Delete from Addresses where AddressId in (select * from AddressesToDelete)

Сега неговата база данни е актуална. Няма повреди в целостта поради изтриване на адрес. Имайте предвид, че въпреки че връщаме данни от актуализацията и първото изтриване, това не означава, че трябва да ги използваме. Не съм сигурен дали можете да поставите изтриване в CTE без върнати данни (Моят SQL също може да греши при използването на връщане от актуализация - не успях да тествам това, тъй като Darth V. беше в капризно настроение.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Показване на изображение от база данни PostgreSQL, bytea

  2. алтернатива на mysql_insert_id за postgresql

  3. Как да настроите отдалечена връзка с PostgreSQL

  4. Добавете сортиране без значение на малки и големи букви към PostgreSQL

  5. CREATE EXTENSION postgis се проваля,