Как заставить 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
является недопустимым значением. Или, по крайней мере, если вы установите его в 0, вы в основном говорите MySQL: "пожалуйста, вставьте следующий идентификатор в это поле."
теперь, я полагаю, я мог бы поставить INSERT
затем UPDATE
запрос в мой файл SQL, но есть ли способ сказать MySQL в целом, что да, я действительно хочу вставить 0
в этой области?
4 ответа:
от ответа я получил здесь:
вы можете использовать:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
, который, как описано здесь, не позволит MySQL интерпретировать идентификатор вставки / обновления 0 как следующий идентификатор последовательности. Такое поведение будет ограничено нулем.
Это то, что я считаю довольно плохим поведением из приложения. Вы должны быть очень осторожны, что он используется последовательно, особенно если вы решите реализовать репликация на более поздний срок.
проверьте свой режим 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'
Если вы не хотите иметь дело с переменными 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;
очевидно, это предполагает, что вы используете целое число со знаком и не использовать отрицательные значения для таблицы идентификаторов.
Fail safe way:
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
- проверяет, если NO_AUTO_VALUE_ON_ZERO уже установлен в sql_mode
- добавляет в sql_mode если не пустой
- устанавливает только сеанс, я рекомендую использовать его только на сеансах, где вам нужно вставить 0