2012-11-28 11 views
51

テーブルを変更しようとしたときにこのエラーが発生しました。外部キー制約で使用される列を変更できません

Error Code: 1833. Cannot change column 'person_id': used in a foreign key constraint 'fk_fav_food_person_id' of table 'table.favorite_food' 

ここでは、正常に実行されたCREATE TABLE STATEMENTがあります。

CREATE TABLE favorite_food(
    person_id SMALLINT UNSIGNED, 
    food VARCHAR(20), 
    CONSTRAINT pk_favorite_food PRIMARY KEY(person_id,food), 
    CONSTRAINT fk_fav_food_person_id FOREIGN KEY (person_id) 
    REFERENCES person (person_id) 
); 

私はこの文を実行しようとしましたが、上記のエラーが発生しました。

ALTER TABLE person MODIFY person_id SMALLINT UNSIGNED AUTO_INCREMENT; 

答えて

52

外部キーフィールドと参照の型と定義は同じでなければなりません。 これは、外部キーがフィールドのタイプを変更できないことを意味します。

LOCK TABLES 
    favorite_food WRITE, 
    person WRITE; 

ALTER TABLE favorite_food 
    DROP FOREIGN KEY fk_fav_food_person_id, 
    MODIFY person_id SMALLINT UNSIGNED; 

今、あなたはあなたが

ALTER TABLE person MODIFY person_id SMALLINT UNSIGNED AUTO_INCREMENT; 

が外部キー

ALTER TABLE favorite_food 
    ADD CONSTRAINT fk_fav_food_person_id FOREIGN KEY (person_id) 
      REFERENCES person (person_id); 

UNLOCK TABLES; 

EDIT再作成PERSON_ID変更することができます:上記 追加のロック、感謝を

一つの解決策はこのことでしょうコメント

これを行う際にデータベースに書き込むことを許可しないと、 データ整合性の問題が発生する可能性があります。

私は自分自身以外のセッションのすべての書き込みのクエリは(INSERT, UPDATE, DELETE

上に書き込みロックを追加しましたタイムアウトまたはUNLOCK TABLESまで待ちます。

http://dev.mysql.com/doc/refman/5.5/en/lock-tables.html

を実行しているEDIT 2:OPは外部キーフィールドと参照の型と定義が同じでなければならない」ラインのより詳細な説明を求めました。これは、あなたのタイプを変更するあなたの外部キー禁止しを意味します。フィールド。"それらは型変換せずに比べ できるようMySQL 5.5 Reference Manual: FOREIGN KEY Constraints外部キーと参照キーの列に対応

から

はInnoDBの内部同様の内部データ型を持たなければなりません。整数型 のサイズと符号は同じでなければなりません。文字列型の長さは同じである必要はありません。 の非バイナリ(文字)文字列の場合、文字セットと照合 は同じでなければなりません。

+1

これにトランザクションを使用することを忘れないでください。そうしないと、データベースが破損する可能性があります。 –

+2

残念ながら、MySQLはDDL文のトランザクションをサポートしていません。 DDLクエリが実行される前にオープントランザクションがコミットされています。http://dev.mysql.com/doc/refman/5.5/en/implicit-commit.html –

+0

@FrancoisBourgeois:この行だけで詳しく説明できますか?外部キーフィールドと参照の定義は等しくなければなりません – theJava

0

キー(プライマリまたは外部)を設定すると、そのキーの使用方法に関する制約が設定されます。これによって、使用できる操作が制限されます。実際に列を変更したい場合は、制約のない表を再作成することもできますが、これに対してお勧めします。一般的に言えば、何かをしたいが制約によってブロックされている状況がある場合、制約よりもむしろ何をしたいかを変更することで解決するのが最も良い方法です。

+1

これは* SUCH *役に立たない、役に立たない答えです! – ajmedway

+1

@ajmedway次に、他のユーザーを責めることなく役に立つ回答を書くことができます –

91

あなたは、外部キーのチェックをオフにすることができます:

SET FOREIGN_KEY_CHECKS = 0; 

/* DO WHAT YOU NEED HERE */ 

SET FOREIGN_KEY_CHECKS = 1; 

生産にこれを使用すると、バックアップがないように確認してください。

+2

非常にきちんと私の非生産のシナリオのために行われます。ありがとう。 – redDevil

+0

非常に安全でないようです。データの整合性が失われる可能性がありますか? – hrust

+0

@Synaps - 削除/更新/挿入する場合は可能です。データの損失は、テーブルを変更したり、データベースをシードする場合には発生しません。一方、制約を取り除くので、手動でデータを検証する必要があります。 – Dementic

関連する問題