「Bestelling」という4つの列を持つテーブルがあります。「Id」(PK)、「KlantId」、「Datum」、「BestellingsTypeId」ですが、列Idをauto_incrementにしたいと思いますが、それをしようとすると、このエラーを取得:
ERROR 1062: ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '1' for key 'PRIMARY'
SQL Statement:
ALTER TABLE `aafest`.`aafest_bestelling` CHANGE COLUMN `Id` `Id` INT(11) NOT NULL AUTO_INCREMENT
ERROR: Error when running failback script. Details follow.
ERROR 1046: No database selected
SQL Statement:
CREATE TABLE `aafest_bestelling` (
`Id` int(11) NOT NULL,
`KlantId` int(11) DEFAULT NULL,
`Datum` date DEFAULT NULL,
`BestellingstypeId` int(11) DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
誰もがアイデアを思いつきましたか?
これは、テーブルにIDが0(または負)の既存のレコードが含まれている場合に発生します。既存のすべてのレコードを更新して正の値を使用すると、auto_incrementがその列に設定されます。
編集:一部の人々は、その0がそこに入った方法を尋ねました。明確にするために、MySQLリファレンスマニュアルには、「数値型の場合、デフォルトは0です。ただし、AUTO_INCREMENT属性で宣言された整数型または浮動小数点型の場合、デフォルトはシーケンスの次の値です。」そのため、auto_incrementが有効になる前に数値列の値を指定せずにテーブルで挿入を実行すると、挿入時にデフォルトの0が使用されます。詳細は https://dev.mysql.com/doc/refman/5.0/en/data-type-defaults.html にあります。
1つの行の値が0である列をauto_incrementに変換しようとしたときにも、この問題が発生しました。0の値を一時的に変更する代わりに、設定を使用します。
SET SESSION sql_mode='NO_AUTO_VALUE_ON_ZERO';
セッションのため。
これにより、IDがゼロの場所で列をauto_incrementに変更できました。
ゼロは理想的ではありません。また、auto_increment列で使用することもお勧めしません。残念ながら、それは継承されたデータセットの一部であるため、今のところそれで固執しています。
後で設定(およびその他)をクリアするのが最善です:
SET SESSION sql_mode='';
ただし、現在のクライアントセッションが終了するとクリアされます。
「NO_AUTO_VALUE_ON_ZERO」設定の詳細 here 。
これは、MySQLが適切なauto_increment値を決定できない場合に発生します。あなたの場合、MySQLは1
次のauto_increment値として。ただし、テーブルにはその値を持つ行が既にあります。
この問題を解決する1つの方法は、適切なauto_increment値を自分で選択することです。
ALTER TABLE ... CHANGE COLUMN `Id` `Id` INT(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT = 123456;
(AUTO_INCREMENT=123456
最後に。)
編集:それがどのように発生するか正確にはわかりませんが、回避策があります。
最初に、古いテーブルのような新しいテーブルを作成します。
CREATE TABLE aafest_bestelling_new LIKE aafest_bestelling;
次に、列を変更します
ALTER TABLE `aafest`.`aafest_bestelling_new`
CHANGE COLUMN `Id` `Id` INT(11) NOT NULL AUTO_INCREMENT
新しいデータをダンプします。
INSERT INTO aafest_bestelling_new
(KlantId, Datum, BestellingTypeId)
SELECT
KlantId, Datum, BestellingTypeId
FROM aafest_bestelling;
テーブルを移動します。
RENAME TABLE
aafest_bestelling TO aafest_bestelling_old,
aafest_bestelling_new TO aafest_bestelling;
たぶんいくつかの破損が進行しているかもしれませんが、これはそれも修正します。
追伸:オランダ人として、英語でのコーディングを強くお勧めします;)
この問題を解決するために見つけた最も簡単な方法は、最初にテーブルのAUTO INCREMENT
列を変更する前の値。その列の現在の最大値よりも高い自動増分値を設定していることを確認してください。
ALTER TABLE `aafest`.`aafest_bestelling`
AUTO_INCREMENT = 100,
CHANGE COLUMN `Id` `Id` INT(11) NOT NULL AUTO_INCREMENT
これをMySQL 5.7でテストし、うまく機能しました。
同様の問題がありました。問題は、SystemParadoxが指摘したものと同様のテーブルに_ID = 0
_のレコードがあったことです。次の手順で問題を処理しました。
手順:
x
where x = MAX(id)+1
x+1
_に設定しますx
を_0
_に戻すコード例:
_UPDATE foo SET id = 100 WHERE id = 0;
ALTER TABLE foo MODIFY COLUMN id INT(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE foo AUTO_INCREMENT = 101;
UPDATE foo SET id = 0 WHERE id = 100;
_
これは、主キー列にすでに値があるために発生します。
エラーが言うように...
ALTER TABLEによりauto_incrementの再シーケンスが発生し、キー 'PRIMARY'のエントリ '1'が重複します
これは、列にすでにプライマリキー値があることを意味します1
これに対する解決策は、プライマリ制約を削除してから列を空にすることです。次に、主キーを設定するテーブルを再度変更します。今回は自動インクリメントを使用します。
テーブルがいくつかのレコードだけで比較的新しい場合、テーブルを切り捨ててID値をリセットできます。
TRUNCATE TABLE tablename;
削除の使用リセットしない ID値。
DELETE FROM tablename;
テーブルが空になったら、自動インクリメントを適用できます。
CHANGE COLUMN `Id` `Id` INT(11) NOT NULL AUTO_INCREMENT
このエラーは、複合AUTO_INCREMENT
PRIMARY KEY
を持つMyISAMテーブルがあり、キーを結合しようとしている場合にも発生します
例えば
CREATE TABLE test1( `id` int(11)NOT NULL、 ` ver` int(10)unsigned NOT NULL AUTO_INCREMENT、 PRIMARY KEY( ` id`、 `ver`) )ENGINE = MyISAM DEFAULT CHARSET = utf8; INSERT INTO test1(` id`、 `ver`)VALUES(1、NULL)、 (1、NULL)、(1、NULL)、(2、NULL)、(2、NULL)、(2、NULL); ALTER TABLE test1 DROP PRIMARY KEY、ADD PRIMARY KEY ( `ver`);