2009-03-05 25 views
17

私は、再帰的PARENT_IDで自己参照MySQLのテーブルを持っている:テスト中自己参照MySQLテーブルを空にするにはどうすればよいですか?

CREATE TABLE `recursive` (
    `id` int(11) NOT NULL auto_increment, 
    `parent_id` int(11) default NULL, 
    `name` varchar(100) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `data_categorysource_parent_id` (`parent_id`), 
    CONSTRAINT `parent_id_refs_id_627b4293` 
    FOREIGN KEY (`parent_id`) REFERENCES `data_categorysource` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

、私はそれを空にしたいが、TRUNCATEは失敗します。

TRUNCATE `recursive` 
/* SQL Error: Cannot delete or update a parent row: a foreign key 
constraint fails... 

私は現在、手動ですべてのレコードを削除する必要があり、ツリーの下端から上に向かって作業を開始します。これは小さな木でも厄介です。

簡単な方法はありますか?私はDROPテーブルを作成することはできませんし、他のテーブルが参照するように簡単に再作成します(私は既にそれらを切り捨てて、そこにデータの整合性の問題はないはずです)。

+0

(Tとして(のtable_1からt_DateとしてMAX(日付(table_1_TIME))を選択します)からT.t_Dateを選択)のtable_1から削除あなたはそれを働かせるでしょう。しかし、あなたが自己参照行を持っているなら、あなたは優雅な選択肢がほとんどありません:http://bugs.mysql.com/bug.php?id=7412。一時的にforeign_keysを無効にする方が最適です。 –

+1

oracleのほうが、トランザクションがコミットするまでconstraistsのチェックに惑わされないように、oracleがうまくいくことはほとんどありません。 –

答えて

22

なぜ:

UPDATE 'recursive' SET 'parent_id' = NULL WHERE 'parent_id' IS NOT NULL; 
DELETE FROM 'recursive'; 

+0

"自己参照MySQLテーブルを空にする最良の方法は何ですか?"またはそれのフォームは非常に多くのインターネットサイトに現れ、SOで何度も複製されていますが、質問のこのような単純で、エレガントで、正解がほとんどありません。 +1 – Barzee

1

まあ、少なくともの定義にFOREIGN KEYの定義を追加することができます。これは、参照された行を最初に削除することによってテーブルを切り捨てることができます。

他にもON DELETEタイプがあります。デフォルトはON DELETE NO ACTIONです。

-1

親が表示されない行を繰り返し選択し、テーブルが空になるまで削除します。 (循環がないと仮定して...)

0

または(再帰的な)外部キー制約を削除してから、テーブルを切り捨ててから再度contraintを追加してください。

16

あなただけのテストの目的のために全体を空にしたい場合は、使用します。

SET FOREIGN_KEY_CHECKS = 0; 

// Execute Query 

SET FOREIGN_KEY_CHECKS = 1; 

これは完全に任意の外部キーチェックをバイパスします。

-2

あなたが「`BY recursive`のORDER`。DELETE FROM場合は日付(table_1_TIME)<が

+0

コードをより明確に書式化し、元の質問の識別子を参照してください。 – gwaigh

関連する問題