複数のテーブルから削除しようとしています。これが私のテーブルの様子です
A_has_B ---- B ---- C_has_B
(many to many) (many to many)
BのレコードのIDを指定して、A_has_B、B、およびC_has_Bからすべての行を削除しようとしています。BのIDを参照するA_has_BおよびC_has_Bに外部キーが定義されたinnodbストレージエンジンでMySQLを使用しています。
私は次のように削除を実行しようとしています:
DELETE A_has_B.*, C_has_B.*, B.*
FROM
A
join
B
on (B.B_id = A.B_id)
join
C
on (C.B_id = B.B_id)
where B.B_id IN(1,2, 4);
問題は、クエリを実行すると、mysqlが次のように文句を言うことです。
Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`db`.`C`, CONSTRAINT `fk_C` FOREIGN KEY (`B_id`) REFERENCES `B` (`B_id`) ON DELETE NO ACTION ON UPDATE NO)
どうすればこれを修正できますか?
最も簡単な方法は、各テーブルから個別に削除することです。
-- Remove all connections from A which reference
-- the B-rows you want to remove
DELETE FROM A_has_B
WHERE B_id IN (1,2,4);
-- Remove all connections from C which reference
-- the B-rows you want to remove
DELETE FROM C_has_B
WHERE B_id IN (1,2,4);
-- Finally remove the B-rows
DELETE FROM B
WHERE B_id IN (1,2,4);
MySQLでは、1つのステートメントで複数のテーブルから削除することもできます。ただし、削除の順序を制御する方法はありません。 手動 から:
外部キー制約があるInnoDBテーブルを含む複数テーブルのDELETEステートメントを使用する場合、MySQLオプティマイザーは親子関係とは異なる順序でテーブルを処理する可能性があります。この場合、ステートメントは失敗し、ロールバックします。代わりに、単一のテーブルから削除し、InnoDBが提供するON DELETE機能に依存して、他のテーブルをそれに応じて変更する必要があります。
実際、MySQLでは、外部キー制約のチェックをオフにすることができます
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
--your SQL statements
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
最初の行のステートメントは、MySQLサーバーに外部キーチェックをオフにし、最後の行はそれらをオフにします再びオン(非常に重要)。覚えておくべき2つのこと:
外部キーに「カスケードの削除」を指定できます。親行を削除すると、mysqlエンジンは関連する子テーブルのレコードを削除します
別のステートメントで削除を実行すると、機能します。