简而言之,我有一个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
是一个无效的值.或者至少,如果你把它设置为0,你基本上告诉MySQL,"请将下一个id插入到这个字段中."
现在,我想我可以在我的SQL文件中添加INSERT
一个UPDATE
查询,但有没有办法告诉MySQL一般是的,我实际上想插入0
这个字段?
从答案我在这里:
您可以使用:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
其如所描述的在这里,将防止从MySQL的解释0-2的插入/更新ID为下一个序列ID.此类行为将限制为NULL.
这是我认为应用程序的非常糟糕的行为.您必须非常小心,它始终如一地使用,特别是如果您选择在以后实施复制.
检查您的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的开发页面的主题在此
更新
对于MariaDB,请使用此注释中指出的命令
SET sql_mode='NO_AUTO_VALUE_ON_ZERO'
如果你不想处理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使用负值.
失败安全方式:
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的会话中使用它