Как заставить 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: "Пожалуйста, вставьте следующий id в это поле".

Теперь, я полагаю, я мог бы поставить запрос INSERT then a UPDATE в мой файл SQL, но есть ли способ сообщить MySQL вообще, что да, я действительно хочу вставить 0 в это поле?

Ответ 1

Из ответа я получил здесь:

Вы можете использовать:

SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'

Что, как описано здесь, не позволит MySQL интерпретировать INSERT/UPDATE ID 0 как следующий идентификатор последовательности. Такое поведение будет ограничено NULL.

Это то, что я считаю довольно плохим поведением из приложения. Вы должны быть очень осторожны, чтобы он использовался последовательно, особенно если вы решили реализовать репликацию на более поздний срок.

Ответ 2

Проверьте свой SQL-код с помощью:

SELECT @@[GLOBAL|SESSION].sql_mode;

Если он пуст или не установлен, используйте:

SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'

БУДЬТЕ ОСТОРОЖНЫ! Если вы используете GLOBAL, это не немедленное изменение, вам необходимо перезапустить соединение, чтобы применить настройку.

Итак, если вы, например, восстанавливаете данные из одного БД на другой, и не уверены, применяется ли этот параметр, используйте SESSION для немедленного изменения (он сбрасывает при закрытии соединения). По завершении вставьте значение 0 и оно не изменится, даже если изменяется sql_mode.

В reset этот режим (и другие) использует

SET [GLOBAL|SESSION] sql_mode=''

Значения нулевого автоинкремента не рекомендуются, поскольку они не установлены по умолчанию в базах данных MySQL.

Для получения дополнительной информации проверьте тему mysql dev на этом

Ответ 3

Безопасный способ:

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

Ответ 4

Если вы не хотите калечить переменные 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;

Очевидно, это предполагает, что вы не используете отрицательные значения для идентификаторов таблиц.