如何强制MySQL将0作为有效的自动增量值
长话短说,我有一个SQL文件,我想导入为skel
风格的文件,所以这将重复,以编程方式完成。 我可以编辑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
是一个无效的值。 或者至less,如果将其设置为0,则基本上告诉MySQL:“请在此字段中插入下一个ID”。
现在,我想我可以把INSERT
和UPDATE
查询放到我的SQL文件中,但是有没有办法告诉MySQL,是的,我真的想在这个字段中插入0
?
从我到这里的答案:
您可以使用:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
如下所述,将阻止MySQL将INSERT / UPDATE ID解释为下一个序列ID。 这种行为将被限制为NULL。
这是我认为从应用程序,但非常不好的行为。 您必须非常小心地使用它,特别是如果您select在以后实施复制。
检查你的SQL DB模式:
SELECT @@[GLOBAL|SESSION].sql_mode;
如果没有设置,请使用:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
小心! 如果您使用GLOBAL
,这不是一个即时更改,您需要重新启动连接来应用设置。
因此,例如,如果要将数据从一个数据库还原到另一个数据库,并且您不确定是否应用了此设置,请使用SESSION
进行立即更改(closures连接时重置)。 完成后,插入0值,即使sql_mode
改变也不会改变。
重置这个模式(和其他)使用
SET [GLOBAL|SESSION] sql_mode=''
不推荐使用零自动增量值,因为它们在MySQL数据库中没有被设置为默认值。
有关更多信息,请查看mysql dev页面主题
如果你不想用mysqlvariables破解,这里有一个有用的黑客:
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的负值。
故障安全方式:
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
- 只设置会话,我build议仅在需要插入0的会话中使用它