Как PDO знает последний вставленный идентификатор в MySQL?

StackOverflow https://stackoverflow.com/questions/4267470

Вопрос

РЕДАКТИРОВАТЬ: Этот вопрос изначально был: Как доктрина знает последний вставленный ID в MySQL? и был связан с Доктрина ORM Mapper. После некоторого копания я узнал, что этот вопрос не связан с Доктрина но Pdo_mysql., MySQL C API И, наконец, - для клиент-сервера MySQL. Я решил изменить название, поэтому, может быть, кто-то найдет ответ на свой вопрос.

Для тех, кто не использует доктрину: мне было любопытно, почему ниже:

mysql_query("INSERT INTO category (name) VALUES('cat')");
echo mysql_insert_id();

или похожие:

$pdo->exec("INSERT INTO category (name) VALUES('cat')");
echo $pdo->lastInsertId();

приведет к одной позиции (без отдельных SELECT LAST_INSERT_ID()) в журнале:

1701 Query    INSERT INTO category (name) VALUES ('cat')

Оригинальный вопрос:

У меня есть 2 стола:

category(id,name)
product(id, name, categoryId)

Я создал новый объект категории и объект продукта. Я присваивал объект категории к объекту продукта. Я не установил никаких идентификаторов:

$product = new Product();
$product->name = 'asdf';

$category = new Category();
$category->name = 'cat';

$product->Category = $category;

После этого я промыл соединение и проверяйте журналы MySQL:

1684 Query  START TRANSACTION
1684 Query  INSERT INTO category (name) VALUES ('cat')
1684 Query  INSERT INTO product (name, categoryid) VALUES ('asdf', '312')
1684 Query  COMMIT

Как учение знала, что недавно созданная идентификатор категории составляет 312? В журналах ничего нет.

Это было полезно?

Решение

Я сделал некоторые исследования и просматриваю какой-то исходный код, поэтому мой ответ может быть немного неправильным и не точным.

Прежде всего, это на самом деле не связано с Доктрина. Доктрина использует Pdo_mysql.. Отказ Но внутри Pdo_mysql. использует то же самое, что mysql_insert_id Функция - родной MySQL C API функция - mysql_insert_id.

Причина, почему нет отделения SELECT LAST_INSERT_ID() заключается в том, что после того, как утверждение выполняется (в моем примере INSERT), сервер отвечает с данными, а некоторые другие включены в ОК Packet), включая insert_id. Отказ Так когда мы огонь mysql_insert_id() Мы не подключаемся к серверу, чтобы получить insert_id - Библиотека MySQL не должна делать это - у нее уже есть эта величина, сохраненная от последнего выполнения запроса (по крайней мере, я думаю, что после анализа файла libmysql.c)

ОК Packet описано здесь: Пакеты общих откликов MySQL - ОК Packet

Другие советы

last_insert_id Работает только для AUTO_INCREMENT столбцы. Это не будет работать, если вы введете значение вручную в AUTO_INCREMENT столбец.

Доктрина будет работать, потому что это так же, как присвоить NULL к нему (хотя вы никогда не специально пишу это). Это вызывает автоматическое увеличение и обеспечивает значение для last_insert_id().

Я включил JPG здесь, чтобы вы могли его увидеть. Надеюсь, поможет!

enter image description here

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top