Как заставить 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