Я застрял в получении последнего идентификатора вставки с Zend framework 2, и я отказался от этого …
Происходит сочетание:
var_dump($this->tableGateway->insert($insert)); var_dump($this->tableGateway->lastInsertValue); var_dump($this->tableGateway->getLastInsertValue()); var_dump($this->tableGateway->getAdapter()->getDriver()->getConnection()->getLastGeneratedValue());
Значение вставляет в таблицу, но каждая строка (кроме первой, которая дает int «1») возвращает значение null. Пожалуйста, не говорите мне, что такая большая структура не дает возможности получить последнее значение идентификатора вставки !?
Вот что я использую:
$data = array()// Your data to be saved; $this->tableGateway->insert($data); $id = $this->tableGateway->lastInsertValue;
Я знаю, что это было немного назад, но, потратив много времени на эту конкретную проблему, я хотел опубликовать решение для будущих Googlers, испытывающих ту же проблему.
Проблема заключается в том, что драйвер Pgsql требует, чтобы имя последовательности возвращало последний id следующим образом:
$adapter->getDriver()->getLastGeneratedValue("sequence_name");
Это работает в 2.3.1. В 2.2.2 (и, возможно, позже) была ошибка, в которой имя не было параметром getLastGeneratedValue в драйвере, поэтому вам нужно было бы вызвать соединение напрямую.
$adapter->getDriver()->getConnection()->getLastGeneratedValue
Вот что я нашел, просмотрев код. Лучшее решение – убедиться, что вы обновили ZF2 и используете
$adapter->getDriver()->getLastGeneratedValue("sequence_name");
В postgres вам нужно настроить SequenceFeature:
... use Zend\Db\TableGateway\Feature; ... public function setDbAdapter( Adapter $adapter ) { ... $this->featureSet = new Feature\FeatureSet(); $this->featureSet->addFeature(new Feature\SequenceFeature('YOUR_FIELD_NAME','YOUR_SEQUENCE_NAME')); $this->initialize(); }
Теперь $this->tableGateway->getLastInsertValue();
должно сработать.
Хорошо, я знаю, что вопрос несколько месяцев, хотя может быть полезно для тех, кто ищет решение этой проблемы, чтобы получить последние значения вставки, лучший способ – получить значение из интерфейса адаптера
do your insert //then $id = $adapter->getDriver()->getLastGeneratedValue();
Это хорошо сработало для базы данных mysql
В App\Model\AlbumTable
который расширяет AbstractTableGateway
я получаю последний id с помощью $inserted_id = $this->lastInsertValue;
В качестве примера:
if ($id == 0) { $this->insert($data); $inserted_id = $this->lastInsertValue; } elseif ($this->getAlbum($id)) { $this->update( $data, array( 'id' => $id, ) ); } else { throw new \Exception('Form id does not exist'); }
Это не работает с oracle oci8, потому что оно еще не реализовано. См. Здесь: https://github.com/zendframework/zf2/blob/master/library/Zend/Db/Adapter/Driver/Oci8/Connection.php#L343
Существует еще одна возможность добавить FeatureSet в TableGateway.
В Module.php вы можете определить (например, пользователь таблицы)
'UserTableGateway' => function ($sm) { $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new UserEntity()); return new TableGateway('user', $dbAdapter, new Feature\SequenceFeature('user','user_id_seq'), $resultSetPrototype);
Но в SequenceFeature есть ошибка. Все в порядке, когда вы используете общедоступную схему. Когда вам нужно использовать другую схему, вы должны использовать Zend \ Db \ Sql \ TableIdentifier;
В этом случае Module.php должен быть:
'UserTableGateway' => function ($sm) { $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new UserEntity()); return new TableGateway(new TableIdentifier('user','someSchema'), $dbAdapter, new Feature\SequenceFeature(new TableIdentifier('user','someSchema'),'user_id_seq'), $resultSetPrototype);
В этом случае будет ошибка с запросом Postgresql SELECT NEXTVAL, потому что Feature \ SequenceFeature будет использовать общедоступную схему вместо определенного в первом аргументе для подготовки запроса
SELECT NEXTVAL ('user_id_seq')
В этом случае sql-запрос должен быть
SELECT NEXTVAL ('someSchema'. 'User_id_seq')