Perl's DBI offers a last_insert_id Method which works with pretty much all database drivers. So while it is available and in practice works, the interface still has to live with the complete lack of standardisation among DBMS. A quote from the DBI man page:
There are several caveats to be aware of with this method if you want to use it for portable applications:
* For some drivers the value may only available immediately after the insert statement has executed (e.g., mysql, Informix).
* For some drivers the $catalog, $schema, $table, and $field parameters are required, for others they are ignored (e.g., mysql).
* Drivers may return an indeterminate value if no insert has been performed yet.
* For some drivers the value may only be available if placeholders have not been used (e.g., Sybase, MS SQL). In this case the value returned
would be from the last non-placeholder insert statement.
* Some drivers may need driver-specific hints about how to get the value. For example, being told the name of the database 'sequence' object
that holds the value. Any such hints are passed as driver-specific attributes in the \%attr parameter.
* If the underlying database offers nothing better, then some drivers may attempt to implement this method by executing ""select max($field)
from $table"". Drivers using any approach like this should issue a warning if "AutoCommit" is true because it is generally unsafe - another
process may have modified the table between your insert and the select. For situations where you know it is safe, such as when you have
locked the table, you can silence the warning by passing "Warn" => 0 in \%attr.
* If no insert has been performed yet, or the last insert failed, then the value is implementation defined.
Given all the caveats above, it's clear that this method must be used with care.
Posted Dec 19, 2011 16:19 UTC (Mon) by khim (subscriber, #9252)
[Link]
Given all the caveats above, it's clear that this method must be used with care.
It must only be used with MySQL, really. If you want to use Oracle and Postgresql then it's much better to use sequences and their nextval and currval directly (not sure about other databases, but they probably have their own ways to do that).
So while it is available and in practice works, the interface still has to live with the complete lack of standardisation among DBMS.
Right. This just shows that SQL driver is completely wrong level of abstraction to try to unify different databases. It's [relatively] easy for ORM layer or application-specific layer to deal with these differences. If you try to do that on SQL driver layer you'll waste huge amount of resources and and the end result will sometimes still not usable (If the underlying database offers nothing better, then some drivers may attempt to implement this method by executing ""select max($field) from $table"").
NOT a way to go. PHP has many problematic warts, but PDO is not one of them.
Yup
Posted Dec 19, 2011 19:35 UTC (Mon) by fatrat (subscriber, #1518)
[Link]
Have you seen Python's SQLAlchemy? It provides an ORM layer but also a really good SQL level layer.
Good try...
Posted Dec 20, 2011 0:35 UTC (Tue) by khim (subscriber, #9252)
[Link]
Even so: I can not see how exactly you can chain multiple INSERTs in one BEGIN/END Oracle statement or execute multiquery in MySQL (like you can do with PHP).
Yup
Posted Dec 20, 2011 7:38 UTC (Tue) by niner (subscriber, #26151)
[Link]
"It must only be used with MySQL, really. If you want to use Oracle and Postgresql then it's much better to use sequences and their nextval and currval directly."
Not really. It covers the simple case quite well which is the vast majority in our applications. If I want to use PostgreSQL features, I'd use returning to get the new ID back to the application without an additional roundtrip.