Postgresql

如何在不使用 ON DELETE CASCADE 的情況下從具有不同外鍵的多個表中刪除數據?

  • May 25, 2015

我有以下 SELECT 語句:

SELECT * FROM "Users" u 
INNER JOIN "Calendars" c ON (u."UserId" = c."UserId")
INNER JOIN "Actions" a ON (c."CalendarId" = a."Calendar_CalendarId")
WHERE u."AuthenticationStatus" = 0 AND u."CreationDate" < now()::date - 7;

這會從三個表“使用者”、“日曆”和“操作”中正確選擇我想要的所有行。它通過將“Users”表的“UserId”與“Calendars”表的外鍵“UserId”以及“Calendars”表的“CalendarId”與“行動”表。

我想將其轉換為 DELETE 語句。我嘗試的是:

DElETE FROM "Users" u 
   USING "Actions" a, "Calendars" c
WHERE u."UserId" = c."UserId" AND 
     c."CalendarId" = a."Calendar_CalendarId" AND 
     u."AuthenticationStatus" = 0 AND 
     u."CreationDate" < now()::date - 7;

但這說:

表“Calendars”上的更新或刪除違反了表“Actions”上的外鍵約束“FK_public.Actions_public.Calendars_Calendar_CalendarId”

詳細資訊:鍵 (CalendarId)=(2) 仍從表“Actions”中引用。

有誰知道我如何將此查詢轉換為 DELETE 語句?

您錯誤地解釋了 delete 語句的語義。使用using子句時,並不意味著記錄也會從這些表中刪除。相反,這些表純粹用於連接以確定需要從中刪除哪些行Users

你基本上有三個選擇:

  1. before delete on Users刪除觸發器中的子行。
  2. on delete cascade約束。
  3. 以正確的順序對涉及的各種表執行多個刪除語句。

在某些情況下,我的偏好實際上是用於on delete cascade約束,但我不會在任何地方使用它們:只是為了能夠一次性刪除給定父級的所有子級的情況。我可能會將它用於“發票”和“發票行”。

當您採用這種方法時,您需要確保只有真正需要能夠從父表中刪除的使用者才具有該權限——沒有使用者或應用程序以表所有者身份登錄!

引用自:https://dba.stackexchange.com/questions/102412