Ответ 1
В документации для LAST_INSERT_ID()
указано:
Если вы используете INSERT IGNORE, и строка игнорируется, счетчик AUTO_INCREMENT не увеличивается и LAST_INSERT_ID() возвращает 0, что отражает, что никакая строка не была вставлена.
Зная это, вы можете сделать это многоэтапным процессом:
- INSERT IGNORE
- если LAST_INSERT_ID(), затем выполнено (добавлена новая строка)
- else SELECT your_primary key FROM yourtable WHERE (ваши вставленные данные УНИКАЛЬНЫЕ ограничения)
Пример с состояниями США:
id | abbrev | other_data
1 | AL | ...
2 | AK |
UNIQUE KEY abbr (abbrev)
Теперь, вставив новую строку:
INSERT IGNORE INTO `states` (`abbrev`,`other_data`) VALUES ('AZ','foo bar');
> OK
SELECT LAST_INSERT_ID();
> "3"
// we have the ID, we're done
Вставка строки, которая будет игнорироваться:
INSERT IGNORE INTO `states` (`abbrev`,`other_data`) VALUES ('AK','duplicate!');
> OK
SELECT LAST_INSERT_ID();
> "0"
// oops, it already exists!
SELECT id FROM `states` WHERE `abbrev` = 'AK'; // our UNIQUE constraint here
> "2"
// there we go!
В качестве альтернативы возможно сделать это одним шагом - используйте REPLACE INTO
вместо INSERT IGNORE INTO
- синтаксис очень похож. Обратите внимание, что при таком подходе есть побочные эффекты - они могут или не могут быть важны для вас:
- REPLACE deletees + воссоздает строку
- поэтому триггеры DELETE запускаются, um,
- первичный идентификатор будет увеличен, даже если существует строка
-
INSERT IGNORE
хранит старые данные строки,REPLACE
заменяет его новыми данными строки