如何强制MySQL将0作为有效的自动增量值


77

长话短说,我有一个要导入为skel样式文件的SQL文件,因此将以编程方式重复进行此操作。我可以根据需要编辑SQL文件,但我不想触摸应用程序本身。

此应用程序userid = 0用来代表匿名用户。它在数据库中还具有一个相关的(空白)条目来表示此“用户”。因此,我这行skel.sql看起来像这样:

INSERT INTO `{{TABLE_PREFIX}}users` VALUES (0, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);

问题在于这uid是一个auto_increment字段,从技术上讲,该字段0是无效值。或者至少,如果将其设置为0,则基本上是在告诉MySQL,“请在该字段中插入下一个ID”。

现在,我想我可以在SQL文件中添加INSERT一个UPDATE查询,但是有没有一种方法可以告诉MySQL,是的,我实际上是想插入0该字段吗?

Answers:


94

从答案我在这里

您可以使用:

SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'

其如所描述的在这里,将防止从MySQL的解释0-2的插入/更新ID为下一个序列ID。这种行为将被限制为NULL。

这就是我认为应用程序中非常糟糕的行为。您必须非常谨慎地确保它的使用一致,尤其是如果您选择以后实施复制时。


17
您必须要注意的一件事:sql_mode是用逗号分隔的标志列表。如果这样做sql_mode='NO_AUTO_VALUE_ON_ZERO',您可能会无意中禁用其他标志
Kip

此解决方案基本上对我有用,但是我的转储还包括一些替换它的地方,这些地方覆盖sql_mode了sql文件的中间部分,然后重置为该变量OLD_SQL_MODE,该变量设置为在脚本末尾恢复。这是压倒一切的我NO_AUTO_VALUE_ON_ZERO在我的脚本使这不是工作的中间。我的解决方案是创建一个新变量INIT_OLD_SQL_MODEi,最后将其重置为,并设置sql_modeNO_AUTO_VALUE_ON_ZERO,然后设置一个新变量,OLD_SQL_MODE使这些临时替代可以重置为
Joshua Fricke

27

使用以下命令检查您的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页面主题

更新资料

对于MariaDB,请使用此注释中指出的命令

SET sql_mode='NO_AUTO_VALUE_ON_ZERO'

这在MariaDB上不起作用,我不得不使用:SET sql_mode='NO_AUTO_VALUE_ON_ZERO'
hiddeneyes02 '18

@ hiddeneyes02这是2010年的帖子,感谢您的评论,我将更新答案:)
IG Pascual

无法正常运作:SELECT @@ [GLOBAL | SESSION] .sql_mode; 确实有效:SELECT @@ SESSION.sql_mode; 确实有效:SELECT @@ GLOBAL.sql_mode;
azoundria

14

如果您不想处理mysql变量,这里有一个有用的技巧:

INSERT INTO `{{TABLE_PREFIX}}users` VALUES (-1, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);

接着

UPDATE `{{TABLE_PREFIX}}users` SET id = 0 where id = -1;

显然,这假定您正在使用带符号的整数,而不是对表ID使用负值。


6
显然,如果您使用的是无符号整数,那么它将无法正常工作。
fnkr '16

7

故障安全方式:

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的会话上使用它
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.