Mysql中插入自增主键为0时的坑

当MySQL表的主键是自增时,插入id=0会导致自动递增。这是由于sql-mode设置影响,特别是缺少NO_AUTO_VALUE_ON_ZERO模式。可以通过临时或永久修改sql-mode,添加NO_AUTO_VALUE_ON_ZERO来避免此行为。临时设置方法是使用SET@sql_mode=...NO_AUTO_VALUE_ON_ZERO...,而永久设置需在my.ini配置文件中添加该模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当一张表tbl的主键id为自增主键时,执行INSERT INTO tbl (id) VALUES (0)时,可能在表中找不到id=0的数据。这都是sql-mode参数惹的祸。当sql-mode中不含NO_AUTO_VALUE_ON_ZERO这个模式时,插入为0的数据时,会把id自动递增后插入。如,当前id最大值是5的话,执行插入id为0的语句后,就会得到id=6的数据。想要解决这个问题就需要重新设置一下sql-mode。

临时设置方式如下:

先用select @@sql_mode;查询一下当前的模式有哪些,然后在最后追加NO_AUTO_VALUE_ON_ZERO即可,设置语句如下:
SET @@sql_mode='STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO'

长久设置要在my.ini里找到sql-mode,在后面添加NO_AUTO_VALUE_ON_ZERO来配置。

### 在 MySQL插入数据后返回自主键的方法 在 MySQL 中,当向表中插入数据,如果该表包含一个定义为 `AUTO_INCREMENT` 的字段,则可以通过特定的语句或函数获取插入记录后生成的自主键值。以下是实现此功能的几种方法: #### 方法一:使用 `LAST_INSERT_ID()` 函数 `LAST_INSERT_ID()` 是 MySQL 提供的一个内置函数,用于返回当前会话中最后一次插入操作生成的自主键值[^1]。此函数的作用范围仅限于当前会话,因此不会受到其他会话的影响。 ```sql INSERT INTO main_user (id, sid) VALUES (1, 1); SELECT LAST_INSERT_ID() AS auto_increment_id; ``` 上述代码中,`INSERT` 语句完成数据插入后,`SELECT LAST_INSERT_ID()` 将返回插入记录的自主键值。 #### 方法二:结合编程语言接口 在使用编程语言(如 PHP、Python 等)与 MySQL 进行交互,大多数数据库连接库都提供了直接获取自主键的功能。例如,在 Python 的 `pymysql` 库中,执行 `insert` 操作后可以调用 `cursor.lastrowid` 获取自主键值[^3]。 以下是一个 Python 示例: ```python import pymysql # 创建数据库连接 connection = pymysql.connect(host='localhost', user='root', password='password', database='test') try: with connection.cursor() as cursor: # 插入数据 sql = "INSERT INTO main_user (id, sid) VALUES (%s, %s)" cursor.execute(sql, (1, 1)) connection.commit() # 获取自主键 last_insert_id = cursor.lastrowid print(f"插入记录的自主键值为: {last_insert_id}") finally: connection.close() ``` #### 方法三:创建自序列临表 如果需要更灵活地管理自字段,可以创建一个专门的自序列表,并通过事务控制手动分配自值[^4]。这种方式适用于需要跨多个表共享自序列的场景。 ```sql -- 创建自序列表 CREATE TABLE `sequence` ( `name` varchar(50) NOT NULL, `current_value` bigint(20) unsigned NOT NULL DEFAULT '0', `increment` int(11) NOT NULL DEFAULT '1', PRIMARY KEY (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 获取并更新自值 START TRANSACTION; UPDATE sequence SET current_value = current_value + increment WHERE name = 'main_user'; SELECT current_value FROM sequence WHERE name = 'main_user'; COMMIT; ``` 以上方法展示了如何通过自定义逻辑实现类似 `AUTO_INCREMENT` 的功能。 --- #### 注意事项 - `LAST_INSERT_ID()` 返回的是当前会话中最后一次插入操作生成的自主键值,因此在多线程或多用户环境下,确保每个会话独立操作。 - 如果表中存在多个 `AUTO_INCREMENT` 字段,则会导致语法错误[^1]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值