Postgresql

在 Postgresql 中使用“從 … 使用 … where 刪除”時,如何從兩個表或其中至少一個表中刪除數據?

  • July 1, 2019

我的 Postgresql 數據庫有這個 sql 腳本:

 DELETE FROM table1
 USING table2
 WHERE table2.frg_table1_id = table1.id
 AND table1.id = $1

table1如果滿足條件,我希望它始終刪除數據table1.id = $1。並且,可選地,也從中刪除相應的數據table2即使 對應的數據 intable2不存在,也必須從中刪除table1

現在的一個問題是,它會從兩個表中刪除數據或從一個表中刪除數據。

我應該如何扭曲我的劇本?

單個DELETE語句僅從單個表中刪除行(暫時忽略表繼承)。因此,如果要從兩個表中刪除,則必須執行兩個刪除語句。

您可以在“一個”語句中執行此操作,但使用一個公共表表達式,該表達式首先從 table2 中刪除,然後從 table1 中刪除:

with t2_deleted as (
 delete from table2
 where frg_table1_id = $1
)
delete from table1
where id = $1;

但最終,這與在單個事務中簡單地執行兩個 DELETE 語句完全相同:

delete from table2
where frg_table1_id = $1;

delete from table1
where id = $1;

就像@a_horse_with_no_name 所說,如果您需要從 2 個單獨的表中刪除數據,則需要執行 2 個單獨的 SQL 語句。但是您發布的查詢似乎相互依賴。因此,一旦您從Table1中刪除數據,您將失去與Table2匹配的鍵值以進行刪除。

因此,我建議您使用參照完整性或在 Table1 上創建觸發器以同時從 Table2 中刪除匹配的記錄。

這是一個例子。

1. --Create Table1
CREATE TABLE Table1
(
                                       EId int,
                                       EName varchar(16)
);

2. --Create Table2
CREATE TABLE Table2
(
                                       EId int,
                                       EName varchar(16)
);

3. --Create Trigger Function to DELETE matching records from Table2
CREATE FUNCTION trg_fn_Table1_After_Delete()
RETURNS TRIGGER AS
$BODY$
BEGIN
DELETE FROM Table2 WHERE EId=Old.Eid;
RETURN NEW;
END $BODY$ LANGUAGE PLPGSQL

4. --Create Trigger on Table1 AFTER DELETE which will execute the function/mathod trg_fn_Table1_After_Delete()
CREATE TRIGGER trg_Table1_After_Delete
AFTER DELETE
ON Table1
FOR EACH ROW
EXECUTE PROCEDURE trg_fn_Table1_After_Delete();

----------------------Insert sample records into Table1
insert into Table1(EId,EName)
values('1','Rajesh');
insert into Table1(EId,EName)
values('2','Ranjan');
insert into Table1(EId,EName)
values('3','Alok Kuwnar'); ---NonMatching Record
----------------------Insert sample records into Table2
insert into Table2(EId,EName)
values('1','Rajesh');
insert into Table2(EId,EName)
values('2','Ranjan');
insert into Table2(EId,EName)
values('4','Ranjan Ranjan');---NonMatching Record

----------------------Validate data
select * from Table1;
select * from Table2;
---------------------Delete data from Table1

DELETE FROM table1
USING table2
WHERE table2.EId = table1.EId
AND Table1.EId=1;

----------------------Re-Validate data
select * from Table1;
select * from Table2;

謝謝!

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