2016-12-29 67 views
0

我有3個表:PostgreSQL的:FOREIGN KEY/ON DELETE CASCADE /觸發

詳細

Detail_Archive

Transaction_Results

Transaction_Results的是,我沒有建立,並具有一個新的表約束條件,我可能完全刪除,但我相信它可能會破壞我假設它的一些功能。

ALTER TABLE Transaction_Results 
ADD Constraint Transaction_Results_Detail_DetailID_fkey FOREIGN KEY (DetailID) 
REFERENCES Details (DetailID) MATCH SIMPLE 
ON UPDATE NO ACTION ON DELETE NO ACTION 

現在,在過去,我簡單地複製和刪除記錄了詳細介紹,併到Detail_Archive

什麼是最常見的方式(S),以保持約束? 我的想法是:可能會使其無效,並將我刪除的值設置爲null,也許將它們移動到引用該表的歸檔版本的附加列,並使其無效。在我需要的代碼中,我將不得不處理這個問題,但對我來說並不是那麼糟糕。

+0

這是一個FOREIGN KEY,它確保對於此表中的每個DetailID值,Details表中都有一個具有相同DetailID值的記錄。 [wiki FK](https://en.wikipedia.org/wiki/Foreign_key) – McNets

+0

是的...這是我的問題.... –

+0

那麼,顯而易見的(也許是錯誤的)答案是停止從「細節「或」細節「。這似乎是「Transaction_Results」的設計目的。最簡單的修復方法是刪除約束條件或使其處於「級聯刪除」狀態。您需要知道行如何在「Transaction_Results」中結束,或者如何找到設計者以確定哪些是合適的。 –

回答

0

所以我採取了蠻力的方法。

ALTER TABLE Transaction_Results DROP CONSTRAINT Transaction_Results_Detail_DetailID_fkey ; 
ALTER TABLE Transaction_Results ALTER COLUMN DetailID DROP NOT NULL; 

ALTER TABLE Transaction_Results ADD COLUMN DetailID_Archive integer NULL; 

CREATE OR REPLACE FUNCTION process_Detail_delete() RETURNS TRIGGER AS $Transaction_Results_trigger$ 
    BEGIN 
     -- 
     -- Update a row in Transaction_Results to reflect the delete performed on Detail, 
     -- make use of the special variable TG_OP to work out the operation. 
     -- 
     IF (TG_OP = 'DELETE') THEN 
      UPDATE Transaction_Results SET DetailID = NULL, DetailID_Archive = OLD.DetailID where DetailID = OLD.DetailID ; 
      RETURN OLD; 

     END IF; 
     RETURN NULL; -- result is ignored since this is an AFTER trigger 
    END; 
$Transaction_Results_trigger$ LANGUAGE plpgsql; 

CREATE TRIGGER Transaction_Results_trigger 
AFTER DELETE ON [Detail] 
    FOR EACH ROW EXECUTE PROCEDURE process_Detail_delete();​