Как использовать SELECT MAX внутри оператора INSERT в MySQL? - PullRequest
0 голосов
/ 09 сентября 2018

Короткая версия: Как получить максимальное значение столбца и использовать результат при добавлении строки с оператором INSERT INTO?

Длинная версия: Я прочитал вопрос: Как использовать оператор «select» в MySQL «вставить» и попытался следовать инструкциям для его ответов. Это мой запрос:

INSERT INTO employee (id, name, state, supervisorId) SELECT MAX(id)+1, 'Dan', state, supervisorId FROM employee WHERE name='Chris';

Но я получаю эту ошибку:

ERROR: 1062: Duplicate entry '7' for key 'PRIMARY'

Причина в том, что у меня есть другая строка, чей идентификатор равен 7. Следовательно,

MAX(id)

не возвращает фактическое максимальное значение, но значение, равное id строки, содержащей «Chris», равной 6.

Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Использование ручного приращения в запросах SQL может привести к условиям гонки. У вас должно быть ограничение AI (автоинкремент) при создании таблицы PK (первичный ключ).

    CREATE TABLE table_name
    (
    table_id int NOT NULL PRIMARY KEY AUTO INCREMENT,
    ....
    );

Если вам абсолютно необходимо использовать ручное приращение, используйте оператор SELECT.

0 голосов
/ 09 сентября 2018

Вы можете исправить это, заменив это:

MAX(id)+1

с этим запросом выбора:

(SELECT MAX(id)+1 FROM employee)

Вот полный запрос:

INSERT INTO employee (id, name, state, supervisorId) SELECT (SELECT MAX(id)+1 FROM employee), 'Dan', state, supervisorId FROM employee WHERE name='Chris';

Обновление:

Хотя этот ответ решает общий вопрос о получении SELECT MAX в запросе INSERT, как предположил @RaymondNijland, лучше использовать большинство функций MySQL auto_increment. Для этого:

1) Создайте столбец первичного ключа с автоматическим приращением:

 ALTER TABLE employee MODIFY COLUMN id INT NOT NULL AUTO_INCREMENT;

2) Удалите идентификатор из вашего запроса вставки:

INSERT INTO employee (name, state, supervisorId) SELECT 'Dan', state, supervisorId FROM employee WHERE name='Chris';
...