У меня проблема с PDO::lastInsertId()
который не возвращает идентификатор (первичный ключ) последней вставленной строки, вместо этого возвращает другое поле, которое является полем внешнего ключа.
PHP-код:
$pdo = new PDO(...); $stmt = $pdo->prepare($sql); $stmt->bindParam(...); $stmt->bindParam(...); $stmt->execute(); $id = $pdo->lastInsertId(); // or $id = $pdo->lastInsertId('services_id_seq'); // I think 'services_id_seq' is not necessary in MySQL // both of them don't return the primary key of last inserted row echo 'last inserted id: ' . $id;
Структура таблицы MySQL:
... id int unsigned not null primary key auto_increment customer_id int unsigned not null user_id int unsigned not null ....
вставленная строка в MySQL:
id customer_id user_id ... 1 19 31 ...
Выход PHP:
last inserted id: 19
Он должен вернуть 1
не 19
. Я не знаю, что-то не так с моим кодом или нет .. или, может быть, это нормальное поведение:?
Возвращаемое значение (документация по PHP):
Если имя имени не было указано для параметра имени, PDO::lastInsertId()
возвращает строку, представляющую ID
строки последней строки, которая была вставлена в базу данных.
Если для параметра имени было указано имя последовательности, PDO::lastInsertId()
возвращает строку, представляющую последнее значение, полученное из указанного объекта последовательности.
Если драйвер PDO
не поддерживает эту возможность, PDO::lastInsertId()
запускает IM001 SQLSTATE
.
Запустите запрос "SELECT LAST_INSERT_ID()"
.
Если возвращенный идентификатор по-прежнему равен 19, а не 2 (или какой-либо первичный ключ должен быть после всех попыток), возникает проблема с MySQL, не относящаяся к PDO. Вы должны исследовать его как отдельный случай (и, возможно, отдельный вопрос), поставляя полный SQL-код, способный работать в консоли, включая создание таблицы, запуск вставки и выбор LAST_INSERT_ID ()
Если эта функция вернет правильное значение, но PDO по-прежнему ошибочна, вы должны, вероятно, сообщить об ошибке на bugs.php.net, снова с полным воспроизводимым кодом и всеми именами программного обеспечения с точными номерами версий.
Только одно, чтобы дать понять: вы уверены, что переменная $sql
в вашем вопросе содержит правильный оператор INSERT, а не что-то вроде INSERT ON DUPLICATE или такого? Или есть триггеры, установленные на этом INSERT?
Недавно я просмотрел PDO :: lastInsertId (), но нашел описание в руководстве недостаточно убедительным (или действительно понятным) и поэтому решил использовать что-то вроде этого:
... $stmt->execute(); $row = $stmt->fetch(); ...
который, кажется, работает для меня.
Я не эксперт по PDO или MySQL, так что это может быть не совсем правильно, но я также подумал, что вышеупомянутый подход обойдет возможную проблему с добавлением другой строки в базу данных (другим пользователем / потоком) между этим потоком execute () и lastInsertID ().
Если вы хотите сохранить lastInsertID (), выяснили ли вы, что в вашей настройке возвращаемый идентификатор должен быть полем автоматического увеличения? Ручной вид намеков на то, что это так, но безнадежно неопределенно (IMHO).
Надеюсь, это поможет.
Привет, Ян.