Fold All / Expand All

2013年5月11日星期六

PHP PDO::lastInsertId, pgsql requires name parameter

PDO::lastInsertId

string PDO::lastInsertId ([ string $name = NULL ] )
Returns the ID of the last inserted row, or the last value from a sequence object, depending on the underlying driver. For example, PDO_PGSQL() requires you to specify the name of a sequence object for the name parameter.

PDO::lastInsertId() 這支的 name 參數在其他 db backend 可能可以不填,但是在 pgsql 的話,不填只會回傳 "0"。

為什麼呢?直接來看 PHP source code 吧。

https://github.com/php/php-src/blob/php-5.3.25/ext/pdo_mysql/mysql_driver.c#L319
MySQL 用「mysql_insert_id()」,不需要 name parameter。

https://github.com/php/php-src/blob/php-5.3.25/ext/pdo_sqlite/sqlite_driver.c#L222
SQLite 用「sqlite3_last_insert_rowid()」,一樣不需要 name parameter。

https://github.com/php/php-src/blob/php-5.3.25/ext/pdo_pgsql/pgsql_driver.c#L345
PostgreSQL 看到 name == NULL,就回傳 "0"。
有 name 才透過「SELECT CURRVAL($1)」拿到我們要的數值。

RETURNING clause, to get last insert id

最近聽到可以在 SQL Insert 時,加上 RETURNING clause,讓 insert 的 row 傳回 id,對於 id 是用 auto increment 的欄位,在 insert 後想要馬上再 update 非常的方便。

這麼好用的東西怎麼以前都沒聽過呢?查了一下後發現,原來 RETURNING clause 不是 SQL standard ,目前看到是 Oracle 和 PostgreSQL 有支援。

在 PHP 使用 PDO 的話,有 PDO::lastInsertId 可以拿到剛 insert 的 id,不過 PHP 文件上也有寫,這個 method 要看後面接的 db backend,有可能不會回傳正確可用的值 XD
This method may not return a meaningful or consistent result across different PDO drivers, because the underlying database may not even support the notion of auto-increment fields or sequences.
MySQL 有「LAST_INSERT_ID()」 ,例如「SELECT LAST_INSERT_ID();」

SQLite 則是「last_insert_rowid()」,對應的 C ineterface 「sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);