web-dev-qa-db-ja.com

MySqlは列をauto_incrementにできません

「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

誰もがアイデアを思いつきましたか?

41
Sander Declerck

これは、テーブルに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 にあります。

128
SystemParadox

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

36
Garoke

これは、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 最後に。)

14
Arnaud Le Blanc

編集:それがどのように発生するか正確にはわかりませんが、回避策があります。

最初に、古いテーブルのような新しいテーブルを作成します。

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;

たぶんいくつかの破損が進行しているかもしれませんが、これはそれも修正します。

追伸:オランダ人として、英語でのコーディングを強くお勧めします;)

13
Evert

この問題を解決するために見つけた最も簡単な方法は、最初にテーブルのAUTO INCREMENT列を変更する前の値。その列の現在の最大値よりも高い自動増分値を設定していることを確認してください。

ALTER TABLE `aafest`.`aafest_bestelling` 
AUTO_INCREMENT = 100, 
CHANGE COLUMN `Id` `Id` INT(11) NOT NULL AUTO_INCREMENT

これをMySQL 5.7でテストし、うまく機能しました。

9
ironpilot

同様の問題がありました。問題は、SystemParadoxが指摘したものと同様のテーブルに_ID = 0_のレコードがあったことです。次の手順で問題を処理しました。

手順:

  1. レコードID 0を更新してx where x = MAX(id)+1
  2. テーブルを変更して主キーと自動増分設定を設定します
  3. シード値を_x+1_に設定します
  4. レコードID 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;
_
2
James Oravec

これは、主キー列にすでに値があるために発生します。

エラーが言うように...

ALTER TABLEによりauto_incrementの再シーケンスが発生し、キー 'PRIMARY'のエントリ '1'が重複します

これは、列にすでにプライマリキー値があることを意味します1

これに対する解決策は、プライマリ制約を削除してから列を空にすることです。次に、主キーを設定するテーブルを再度変更します。今回は自動インクリメントを使用します。

2
Lalit Mehra

テーブルがいくつかのレコードだけで比較的新しい場合、テーブルを切り捨ててID値をリセットできます。

TRUNCATE TABLE tablename;

削除の使用リセットしない ID値。

DELETE FROM tablename;

テーブルが空になったら、自動インクリメントを適用できます。

CHANGE COLUMN `Id` `Id` INT(11) NOT NULL AUTO_INCREMENT
0
Hasan Patel

このエラーは、複合AUTO_INCREMENTPRIMARY 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`); 
0
Timo Huovinen