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

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