MySQL:如果外鍵約束,更新而不是刪除?
我有一個奇怪的問題。我知道插入重複鍵更新。我的問題是,由於外鍵約束而失敗的刪除是否有類似的東西?
例如:
從 table1 中刪除 value=‘something’;
但是,table2 有一個外鍵,它取決於我要在 table1 中刪除的值,因此刪除失敗。我想做這樣的事情:
從表 1 中刪除,其中外鍵上的 value=‘something’ 失敗 update some_other_value=‘something else’;
我知道這看起來很奇怪,但我有充分的理由這樣做(無需詳細說明,它與版本化歷史數據有關,如果在其他地方引用了值,則無法銷毀這些數據。)我可以想當然,如何使用多個查詢來做到這一點,但如果可以的話,我想在一個查詢中做到這一點。我很確定這是不可能的,但我想在放棄之前問一下:)
謝謝!
你不能直接這樣做,因為沒有辦法(我能想到)交替地
UPDATE
或DELETE
從同一個查詢中……通常一個查詢只能做一種類型的CRUD操作(ON DUPLICATE KEY UPDATE
這是一個例外)。但是,您可以使用儲存過程使其“感覺像”單個查詢,您可以在其中
CONTINUE HANDLER
為您預期的外鍵錯誤設置一個。處理程序將擷取錯誤並可用於設置一個變數,您可以測試該變數以查看您是否遇到錯誤,因此還需要嘗試更新查詢。DELIMITER $$ DROP PROCEDURE IF EXISTS delete_or_update $$ CREATE PROCEDURE delete_or_update (IN input_value INT) BEGIN DECLARE hit_fk_error TINYINT DEFAULT 0; DECLARE deleted_row_count INT DEFAULT NULL; DECLARE updated_row_count INT DEFAULT NULL; -- 1451 is probably the error code that will be generated -- Cannot delete or update a parent row: a foreign key constraint fails (%s) -- otherwise, you may need to substitute the correct error code in the next line DECLARE CONTINUE HANDLER FOR 1451 SET hit_fk_error = TRUE; DELETE FROM parent_table WHERE tested_column = input_value; /* arg to the stored proc */ SET deleted_row_count = ROW_COUNT(); IF (hit_fk_error = TRUE) THEN UPDATE parent_table SET some_other_value = 'something_else' WHERE tested_column = input_value; SET updated_row_count = ROW_COUNT(); END If; SELECT deleted_row_count, updated_row_count, hit_fk_error; END $$ DELIMITER ;
這將嘗試刪除;如果遇到外鍵錯誤,它將嘗試更新(並且外鍵錯誤將被抑制)。該過程將返回一個記錄集,其中包含每個查詢影響的行數以及是否發生外鍵錯誤。如果“input_value”不是一個
INT
或WHERE
子句更複雜,則需要相應地修改結構。我在這裡看到的潛在問題是,如果 where 子句太寬泛,並且匹配一些會導致外鍵錯誤的行和其他不會導致外鍵錯誤的行,那麼查詢將不會單獨處理這些行。這可以通過一個更複雜的過程來完成,該過程使用游標來查找 where 子句中的行,並在辨識它們之後嘗試通過主鍵單獨刪除或更新它們。這種方法效率較低,但更精確。