如何强制 MySQL 将 0 作为有效的自增值
Posted
技术标签:
【中文标题】如何强制 MySQL 将 0 作为有效的自增值【英文标题】:How to force MySQL to take 0 as a valid auto-increment value 【发布时间】:2010-11-11 15:56:55 【问题描述】:长话短说,我有一个 SQL 文件,我想将其导入为 skel
样式文件,所以这将通过编程重复完成。我可以随心所欲地编辑 SQL 文件,但我不想接触应用程序本身。
此应用程序使用userid = 0
代表匿名用户。它还在数据库中有一个相关的(空白)条目来表示这个“用户”。因此,我的skel.sql
中的行看起来像这样:
INSERT INTO `TABLE_PREFIXusers` VALUES (0, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);
问题在于uid
是一个auto_increment
字段,从技术上讲,0
是一个无效值。或者至少,如果将其设置为 0,则基本上是在告诉 mysql,“请在此字段中插入下一个 id。”
现在,我想我可以将 INSERT
然后 UPDATE
查询放入我的 SQL 文件中,但是有没有办法告诉 MySQL 是的,我实际上想在这个字段中插入 0
?
【问题讨论】:
【参考方案1】:从我得到的答案here:
你可以使用:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
如here 所述,这将阻止 MySQL 将 INSERT/UPDATE ID 0 解释为下一个序列 ID。这种行为将被限制为 NULL。
不过,我认为这是应用程序中非常糟糕的行为。您必须非常小心,以确保始终如一地使用它,尤其是当您选择在以后实施复制时。
【讨论】:
您必须注意的一件事:sql_mode
是一个以逗号分隔的标志列表。如果您使用sql_mode='NO_AUTO_VALUE_ON_ZERO'
,您可能会无意中禁用其他标志
这个解决方案基本上对我有用,但是我的转储还包括一些地方,它覆盖了 sql 文件中间的sql_mode
,然后重置为设置为的变量OLD_SQL_MODE
回到脚本末尾。这在我的脚本中间覆盖了我的NO_AUTO_VALUE_ON_ZERO
,使其无法正常工作。我的解决方案是创建一个 INIT_OLD_SQL_MODE
的新变量,我曾经在最后重置为,在我将 sql_mode
设置为 NO_AUTO_VALUE_ON_ZERO
后,我设置了一个新变量 OLD_SQL_MODE
,这些临时覆盖可以重置为跨度>
【参考方案2】:
检查您的 sql DB 模式:
SELECT @@[GLOBAL|SESSION].sql_mode;
如果为空或未设置,请使用:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
小心!如果您使用 GLOBAL
,则不会立即更改,您需要重新启动连接才能应用设置。
因此,例如,如果您要将数据从一个数据库恢复到另一个数据库,并且您不确定是否应用了此设置,请使用 SESSION
立即更改(它会重置关闭连接时)。完成后,插入0值,即使sql_mode
改变也不会改变。
要重置此模式(和其他),请使用
SET [GLOBAL|SESSION] sql_mode=''
不建议使用零自动增量值,因为它们在 MySQL 数据库中未设置为默认值。
更多信息请查看mysql dev page topic
更新
对于 MariaDB,使用this comment 中指出的命令
SET sql_mode='NO_AUTO_VALUE_ON_ZERO'
【讨论】:
这在 MariaDB 上不起作用,我不得不使用它:SET sql_mode='NO_AUTO_VALUE_ON_ZERO'
@hiddeneyes02 这是2010年的帖子,谢谢你的评论,我会更新答案:)
无效:SELECT @@[GLOBAL|SESSION].sql_mode;确实有效: SELECT @@SESSION.sql_mode;确实有效:SELECT @@GLOBAL.sql_mode;【参考方案3】:
如果你不想处理 mysql 变量,这里有一个有用的 hack:
INSERT INTO `TABLE_PREFIXusers` VALUES (-1, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);
然后
UPDATE `TABLE_PREFIXusers` SET id = 0 where id = -1;
显然,这假设您使用的是有符号整数,而不是表 id 使用负值。
【讨论】:
显然,如果您使用的是无符号整数,则它不起作用。【参考方案4】:故障安全方式:
SET @@session.sql_mode =
CASE WHEN @@session.sql_mode NOT LIKE '%NO_AUTO_VALUE_ON_ZERO%'
THEN CASE WHEN LENGTH(@@session.sql_mode)>0
THEN CONCAT_WS(',',@@session.sql_mode,'NO_AUTO_VALUE_ON_ZERO') -- added, wasn't empty
ELSE 'NO_AUTO_VALUE_ON_ZERO' -- replaced, was empty
END
ELSE @@session.sql_mode -- unchanged, already had NO_AUTO_VALUE_ON_ZERO set
END
检查是否已在 sql_mode 中设置 NO_AUTO_VALUE_ON_ZERO
如果不为空,则添加到 sql_mode
仅设置会话,我建议仅在需要插入 0 的会话上使用它
【讨论】:
以上是关于如何强制 MySQL 将 0 作为有效的自增值的主要内容,如果未能解决你的问题,请参考以下文章