amphp / postgres

Async Postgres client for PHP based on Amp.
MIT License
97 stars 20 forks source link

How to get the last inserted ID? #25

Closed RonEskinder closed 4 years ago

RonEskinder commented 4 years ago

Can you provide an example with an INSERT returning the last inserted ID into a variable, thanks

enumag commented 4 years ago

I believe you can use this method. However it seems to be only available with ext-pgsql.

Anyone knows if it's possible to get last insert id with ext-pq?

On a side note I recommend using UUIDs instead.

RonEskinder commented 4 years ago

Can you provide an example? thanks

enumag commented 4 years ago

Like this, I think.

Amp\Loop::run(function () {
    $config = Postgres\ConnectionConfig::fromString('host=localhost user=postgres');

    /** @var \Amp\Postgres\Connection $connection */
    $connection = yield Postgres\connect($config);

    /** @var \Amp\Sql\CommandResult $result */
    $result = yield $connection->query('INSERT INTO ...');

    $id = $result->getLastOid();
});
RonEskinder commented 4 years ago

Tried, getting nothing, empty value on "id", any other ideas?

enumag commented 4 years ago

Unfortunately no.

kelunik commented 4 years ago

@RonEskinder Generally, you'll get the last inserted ID via RETURNING statements in the query in postgres, e.g.

INSERT INTO person (lastname, firstname) VALUES ('Doe', 'John') RETURNING id;
enumag commented 4 years ago

@kelunik But how do you get it from the CommandResult? And if it's the method i mentioned above then how to do it when ext-pq is used?

On Mon, Mar 9, 2020, 22:56 Niklas Keller notifications@github.com wrote:

@RonEskinder https://github.com/RonEskinder Generally, you'll get the last inserted ID via RETURNING statements in the query in postgres, e.g.

INSERT INTO person (lastname, firstname) VALUES ('Doe', 'John') RETURNING id;

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/amphp/postgres/issues/25?email_source=notifications&email_token=AAEDWRTPVH4N4D2DDKT4V5LRGVQ2LA5CNFSM4LEPXRT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOJG35Q#issuecomment-596798966, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEDWRXC5NWRBRJ3NEUV6C3RGVQ2LANCNFSM4LEPXRTQ .

RonEskinder commented 4 years ago

Tried this and im getting an error

use Amp\Postgres;
use Amp\Postgres\ConnectionConfig;

Amp\Loop::run(function () {
    $config = Postgres\ConnectionConfig::fromString($conn);

    /** @var \Amp\Postgres\Connection $connection */
    $connection = yield Postgres\connect($config);

    /** @var \Amp\Sql\CommandResult $result */
    $statement = yield $pool->prepare('INSERT INTO "public"."tc_fuel_merchant"("merchantName", "brand", "merchantAddress", "merchantCity", "merchantState", "merchantZip") VALUES (?, ?, ?, ?, ?, ?) RETURNING id;');
    $result = yield $statement->execute([$merchantName, $brand, $merchantAddress, $merchantCity, $merchantState, $merchantZip]);

    //$id = pg_getlastoid($result);
    $id = $result->getLastOid();
});

Error: PHP Fatal error: Uncaught Error: Call to undefined method Amp\Postgres\PooledResultSet::getLastOid()

trowski commented 4 years ago

As @kelunik suggested, you need to use RETURNING in Postgres.

$sql = "INSERT INTO person (lastname, firstname) VALUES (?, ?) RETURNING id;"
$statement = yield $pool->prepare($sql);
$result = yield $statement->execute(['Doe', 'John']);
if (!yield $result->advance()) {
    throw new \RuntimeException("Insertion failed.");
}
$id = $result->getCurrent()['id'];

Ignore PgsqlCommandResult::getLastOid(). Driver-specific methods that are misleading shouldn't have existed. I'll deprecate it and add something like the above to the docs.

RonEskinder commented 4 years ago

This worked like a charm, thanks!