Как заставить MySQL принять 0 в качестве допустимого значения автоматического приращения
короче говоря, у меня есть файл SQL, который я хочу импортировать как skel
файл стиля, поэтому это будет сделано повторно, программно. Я могу редактировать файл SQL, как хочу, но я бы предпочел не трогать само приложение.
это приложение использует userid = 0
для представления анонимных пользователей. Он также имеет соответствующую (пустую) запись в базе данных для представления этого "пользователя". Следовательно, линия в my 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 в это поле."
теперь, я полагаю, я мог бы поставить INSERT
затем UPDATE
запрос в мой файл SQL, но есть ли способ сказать MySQL в целом, что да, я действительно хочу вставить 0
в этой области?
4 ответов
из ответа я получил здесь:
вы можете использовать:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
, который, как описано здесь, помешает MySQL интерпретировать идентификатор вставки / обновления 0 как следующий идентификатор последовательности. Такое поведение будет ограничено 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 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