且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

更新时间:2022-10-01 08:59:00

 今天 给开发更新了表结构后,遇到了这样的问题:

  mysql> INSERT INTO `sg_medal_action` (`action_name`,`action_code`,`status`) VALUES ('121212','testCode',2);

  ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

  问题重现:

  修改前,表的结构如下:

    mysql> show create table sg_medal_action\G

  *************************** 1. row ***************************

         Table: sg_medal_action

  Create Table: CREATE TABLE `sg_medal_action` (

   `action_id` int(10) unsigned NOT NULL,

   `action_code` char(20) NOT NULL,

   `action_name` varchar(80) NOT NULL,

   `status` tinyint(4) unsigned DEFAULT '1',

    PRIMARY KEY (`action_id`,`action_code`)

  ) ENGINE=InnoDB DEFAULT CHARSET=utf8

  1 row in set (0.00 sec)

  

  表的状态信息如下:

  mysql> show table status like 'sg_medal_action'\G

  *************************** 1. row ***************************

           Name: sg_medal_action

           Engine: InnoDB

          Version: 10

       Row_format: Compact

             Rows: 7

   Avg_row_length: 2340

      Data_length: 16384

  Max_data_length: 0

     Index_length: 0

        Data_free: 0

   Auto_increment: NULL

      Create_time: 2011-11-03 16:36:12

      Update_time: NULL

       Check_time: NULL

        Collation: utf8_general_ci

         Checksum: NULL

   Create_options: 

          Comment: 

  1 row in set (0.00 sec)

  表里面的内容:

  mysql> select * from sg_medal_action;

  +-----------+---------------+--------------------+--------+

  | action_id | action_code   | action_name        | status |

  +-----------+---------------+--------------------+--------+

  |         1 | buyAddr       | 购买线索数量       |      1 |

  |         2 | fans          | 粉丝数             |      1 |

  |         3 | header        | 上传头像           |      1 |

  |         4 | login         | 登录               |      1 |

  |         5 | mark          | 锚点数             |      1 |

  |         6 | showGoods     | 晒货数量           |      1 |

  |         7 | showGoodsLove | 晒货喜欢数         |      1 |

  +-----------+---------------+--------------------+--------+

  7 rows in set (0.00 sec)

  修改表结构语句如下:

  alter table sg_medal_action drop primary key;

  alter table sg_medal_action add primary key(action_id);

 

  执行完以上操作后,表结构、表状态信息分别如下:

  mysql> show create table sg_medal_action\G

  *************************** 1. row ***************************

         Table: sg_medal_action

  Create Table: CREATE TABLE `sg_medal_action` (

    `action_id` int(10) unsigned NOT NULL,

    `action_code` char(20) NOT NULL,

    `action_name` varchar(80) NOT NULL,

    `status` tinyint(4) unsigned DEFAULT '1',

    PRIMARY KEY (`action_id`)

  ) ENGINE=InnoDB DEFAULT CHARSET=utf8

  1 row in set (0.00 sec)

  mysql> show table status like 'sg_medal_action'\G

  *************************** 1. row ***************************

             Name: sg_medal_action

           Engine: InnoDB

          Version: 10

       Row_format: Compact

             Rows: 7

   Avg_row_length: 2340

      Data_length: 16384

  Max_data_length: 0

     Index_length: 0

        Data_free: 0

   Auto_increment: NULL

      Create_time: 2011-11-03 16:42:45

      Update_time: NULL

       Check_time: NULL

        Collation: utf8_general_ci

         Checksum: NULL

   Create_options: 

          Comment: 

  1 row in set (0.00 sec)

  mysql> 

  执行 insert 操作,如下:

  mysql> INSERT INTO `sg_medal_action` (`action_name`,`action_code`,`status`) VALUES ('121212','testCode',2);

  Query OK, 1 row affected, 1 warning (0.00 sec)

  插入操作执行成功,查看表中记录情况如下:

  mysql> select * from sg_medal_action;

  +-----------+---------------+--------------------+--------+

  | action_id | action_code   | action_name        | status |

  +-----------+---------------+--------------------+--------+

  |         0 | testCode      | 121212             |      2 |

  |         1 | buyAddr       | 购买线索数量       |      1 |

  |         2 | fans          | 粉丝数             |      1 |

  |         3 | header        | 上传头像           |      1 |

  |         4 | login         | 登录               |      1 |

  |         5 | mark          | 锚点数             |      1 |

  |         6 | showGoods     | 晒货数量           |      1 |

  |         7 | showGoodsLove | 晒货喜欢数         |      1 |

  +-----------+---------------+--------------------+--------+

  8 rows in set (0.00 sec)

  再执行一次插入操作,报错如下:

  

  mysql> INSERT INTO `sg_medal_action` (`action_name`,`action_code`,`status`) VALUES ('345','Code',2);

  ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

  

  这说明每次往表中插入记录的PRIMARY值均为0。

  

  解决问题思路:

  1、老的表结构,使用的复合索引——“PRIMARY KEY (`action_id`,`action_code`)”,没有指定 auto_increment 的值;

  2、删除原来主键,重新创建新主键时(alter table sg_medal_action add primary key(action_id);

),也未指定 auto_increment的值,所以在创建了新主键后,再看表 sg_medal_action 的状态时, Auto_increment 一栏的值仍为 NULL;

  3、mysql 不支持 “alter table sg_medal_action add auto_increment primary key(action_id);”这样的语句,请详看 alter 的语法 http://dev.mysql.com/doc/refman/5.0/en/alter-table.html ;

  4、解决问题

  mysql> alter table sg_medal_action modify column action_id int unsigned auto_increment;

      Query OK, 7 rows affected (0.06 sec)

      Records: 7  Duplicates: 0  Warnings: 0

  

  执行了此操作后,再查看 sg_medal_action 表结构及状态信息,如下:

  mysql> show create table sg_medal_action\G

  *************************** 1. row ***************************

         Table: sg_medal_action

  Create Table: CREATE TABLE `sg_medal_action` (

    `action_id` int(10) unsigned NOT NULL AUTO_INCREMENT,

    `action_code` char(20) NOT NULL,

    `action_name` varchar(80) NOT NULL,

    `status` tinyint(4) unsigned DEFAULT '1',

    PRIMARY KEY (`action_id`)

  ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8

  1 row in set (0.00 sec)

  

  mysql> show table status like 'sg_medal_action'\G

  *************************** 1. row ***************************

             Name: sg_medal_action

           Engine: InnoDB

          Version: 10

       Row_format: Compact

             Rows: 8

   Avg_row_length: 2048

      Data_length: 16384

  Max_data_length: 0

     Index_length: 0

        Data_free: 0

   Auto_increment: 8

      Create_time: 2011-11-03 16:25:58

      Update_time: NULL

       Check_time: NULL

        Collation: utf8_general_ci

         Checksum: NULL

   Create_options: 

          Comment: 

  1 row in set (0.00 sec)

  再执行insert操作,如下:

  mysql> INSERT INTO `sg_medal_action` (`action_name`,`action_code`,`status`) VALUES ('121212','testCode',2);

  Query OK, 1 row affected (0.00 sec)

  

  查询其结果:

  mysql> select * from sg_medal_action;

  +-----------+---------------+--------------------+--------+

  | action_id | action_code   | action_name        | status |

  +-----------+---------------+--------------------+--------+

  |         1 | buyAddr       | 购买线索数量       |      1 |

  |         2 | fans          | 粉丝数             |      1 |

  |         3 | header        | 上传头像           |      1 |

  |         4 | login         | 登录               |      1 |

  |         5 | mark          | 锚点数             |      1 |

  |         6 | showGoods     | 晒货数量           |      1 |

  |         7 | showGoodsLove | 晒货喜欢数         |      1 |

  |         8 | testCode      | 121212             |      2 |

  +-----------+---------------+--------------------+--------+

  8 rows in set (0.00 sec)

  再插入一行:

  mysql> INSERT INTO `sg_medal_action` (`action_name`,`action_code`,`status`) VALUES ('345','Code',2);

  Query OK, 1 row affected (0.01 sec)

  查询结果:

  mysql> select * from sg_medal_action;

  +-----------+---------------+--------------------+--------+

  | action_id | action_code   | action_name        | status |

  +-----------+---------------+--------------------+--------+

  |         1 | buyAddr       | 购买线索数量       |      1 |

  |         2 | fans          | 粉丝数             |      1 |

  |         3 | header        | 上传头像           |      1 |

  |         4 | login         | 登录               |      1 |

  |         5 | mark          | 锚点数             |      1 |

  |         6 | showGoods     | 晒货数量           |      1 |

  |         7 | showGoodsLove | 晒货喜欢数         |      1 |

  |         8 | testCode      | 121212             |      2 |

  |         9 | Code          | 345                |      2 |

  +-----------+---------------+--------------------+--------+

  9 rows in set (0.00 sec)

  OK,问题 处理到此结束。

  总结下:

    auto_increment 与 primary key 如果不一起存在,则做 insert 操作时,必须自己指定 primary key 列的值;

    小测试如下:

    mysql> create table dd (i int primary key,b char(10));

    Query OK, 0 rows affected (0.01 sec)

    mysql> show create table dd\G

    *************************** 1. row ***************************

           Table: dd

    Create Table: CREATE TABLE `dd` (

      `i` int(11) NOT NULL,

      `b` char(10) DEFAULT NULL,

      PRIMARY KEY (`i`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8

    1 row in set (0.00 sec)

 

    mysql> insert into dd(b) values('dkf');

    Query OK, 1 row affected, 1 warning (0.00 sec)

 

    mysql> select * from dd;

    +---+------+

    | i | b    |

    +---+------+

    | 0 | dkf  |

    +---+------+

    1 row in set (0.00 sec)

    mysql> insert into dd(b) values('lll');

    ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

    mysql> select * from dd;

    +---+------+

    | i | b    |

    +---+------+

    | 0 | dkf  |

    +---+------+

    1 row in set (0.00 sec)

  

    mysql> insert into dd values(1,'lll');

    Query OK, 1 row affected (0.01 sec)

    mysql> select * from dd;

    +---+------+

    | i | b    |

    +---+------+

    | 0 | dkf  |

    | 1 | lll  |

    +---+------+

    2 rows in set (0.00 sec)

    mysql> insert into dd(b) values('lll');

    ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

    另外,请参阅下InnoDB引擎下update操作对atuo_increment影响的文章 http://bugs.mysql.com/bug.php?id=38839

  参阅:http://www.phwinfo.com/forum/comp-databases-mysql/317343-error-1062-23000-duplicate-entry-0-key-1-a.html

本文转自奔跑在路上博客51CTO博客,原文链接http://blog.51cto.com/qiangsh/1626439如需转载请自行联系原作者


qianghong000