2010-04-04 18 views
1

我有兩個表:如何配置要在父表更新上刪除的引用?

info: ID, fee_id 

fee: ID, amount 

和它們之間的引用(SQL Server 2008):

ALTER TABLE info WITH CHECK ADD CONSTRAINT FK_info_fee FOREIGN KEY(fee_id) 
REFERENCES fee (ID) 
ALTER TABLE info CHECK CONSTRAINT FK_info_fee 
GO 

如何配置此引用,方式,以便在fee紀錄將被刪除,如果info.fee_id變成NULL

編輯:或者可能設置info.fee_idNULL刪除fee中的相應記錄。

反正我能做到這樣:

UPDATE info SET fee = NULL WHERE = .. 
DELETE FROM fee WHERE .. 

,但我敢肯定,這可以通過數據庫本身來完成。

回答

1

的幾點思考:

  • 如果你有一個:一個參考則可以在2個表結合起來?
  • 從小孩到父母的鑽取很奇怪:如果它是1:1,那麼您是否可以逆轉FK方向並簡單地CASCADE NULL?
  • 否則,你將不得不使用觸發器,但假設1:1讓我感到不安...
  • ...除非你有info_fee.fee_id

像這樣一個唯一約束/索引:

ALTER TABLE info WITH CHECK ADD 
CONSTRAINT FK_fee_info_fee FOREIGN KEY (id) REFERENCES info_fee (fee_ID) ON DELETE SET NULL 
+0

謝謝!似乎很有用!一個問題:據我所知,在這個配置中,我必須刪除'fee','info'中的相應列將被自動清空。對? – abatishchev 2010-04-05 11:16:39

+0

是的,這是「ON DELETE SET NULL」。在父母刪除時,通過FK設置的子行爲空 – gbn 2010-04-05 11:22:00

+0

哦,不,這不是我需要的。父記錄必須始終存在。孩子可以被刪除,並且'info.fee_id'必須爲空(以這2個操作的任何順序)。是否可以使用'REFERENCE'?或者只使用'TRIGGER'? – abatishchev 2010-04-05 11:31:08

2

你可能不想這樣做。如果多個info行引用相同的fee行,您會發生什麼情況?

如果你真的想做這樣的事情,那麼在信息表中添加邏輯到AFTER UPDATE, DELETE trigger可能是一條路。檢查是否有其他info行引用相同的fee行,如果沒有,請刪除fee行。

+0

我有一對一的參考,即只有在'fee'一個記錄指向'info'。 – abatishchev 2010-04-05 09:22:10

+0

@abatishchev:你是否有數據庫邏輯限制'fee'表只包含對每個'info'行的引用?如果你不這樣做,遲早你會得到多個引用。 – 2010-04-05 16:07:33

+0

我在生產中的'收費'表也有'金額'欄,並保存'邀請朋友'的數據。因此不通過數據庫邏輯而是通過實際業務邏輯來約束:)只有一個客戶端可以邀請一個新的客戶端。 – abatishchev 2010-04-05 17:14:04

0

如果您確實打算在fee_id設置爲空時刪除行,則一種方法是觸發器update。在更新觸發器中,deleted表包含舊版本的更新行,inserted表包含新版本。通過加入他們,你就可以採取行動時fee_id變化null

CREATE TRIGGER deleteFee 
ON info 
FOR UPDATE 
AS 
    DELETE FROM Fee 
    WHERE Fee.id IN (
     SELECT old.fee_id 
     FROM deleted old 
     JOIN inserted new ON old.id = new.id 
     WHERE old.fee_id = fee.id 
     AND new.fee_id is null 
    ) 

這是棘手當多個信息行指的是同樣的費用。如果任何信息行設置爲空,費用將被刪除。一個完整的同步觸發將避免:

CREATE TRIGGER deleteFee 
ON info 
FOR UPDATE 
AS 
    DELETE FROM Fee 
    WHERE NOT EXISTS (
     SELECT * 
     FROM Info 
     WHERE Fee.id = Info.fee_id 
    ) 

但這可以有其他意想不到的後果,就像在響應更新刪除一半的費用表。在這種情況下,與大多數情況一樣,觸發器增加了比他們解決的更多的複雜性。觸發器是邪惡的,應該避免幾乎任何代價。

+2

刪除級聯會以其他方式進行:刪除'fee'行時刪除'info'行,不是嗎? – 2010-04-04 21:28:30

+0

@Michael Petrotta:你說得對,我已經取消了cascase,我會upvote你的回答:) – Andomar 2010-04-04 21:39:55

相關問題