PostgreSQL的mysql_insert_id替代
时间:2020-03-05 18:51:16 来源:igfitidea点击:
PostgreSQL的mysql_insert_id()php函数有替代方法吗?大多数框架通过找到ID中使用的序列的当前值来部分解决问题。但是,有时主键不是序列列。
解决方案
回答
签出INSERT语句的RETURNING可选子句。 (链接到官方PostgreSQL文档)
但基本上,我们可以这样做:
INSERT INTO table (col1, col2) VALUES (1, 2) RETURNING pkey_col
并且INSERT语句本身返回受影响的行的ID(或者我们指定的任何表达式)。
回答
从php.net:
$res=pg_query("SELECT nextval('foo_key_seq') as key"); $row=pg_fetch_array($res, 0); $key=$row['key']; // now we have the serial value in $key, let's do the insert pg_query("INSERT INTO foo (key, foo) VALUES ($key, 'blah blah')");
这应该始终提供唯一的密钥,因为从数据库检索到的密钥将永远不会再次检索。
回答
从PostgreSQL的角度来看,采用伪代码:
* $insert_id = INSERT...RETURNING foo_id;-- only works for PostgreSQL >= 8.2. * INSERT...; $insert_id = SELECT lastval(); -- works for PostgreSQL >= 8.1 * $insert_id = SELECT nextval('foo_seq'); INSERT INTO table (foo...) values ($insert_id...) for older PostgreSQL (and newer PostgreSQL)
pg_last_oid()仅在有OID的地方起作用。自PostgreSQL 8.1起,默认情况下OID已关闭。
因此,根据我们使用的PostgreSQL版本,我们应该选择上述方法之一。当然,理想情况下,当然要使用数据库抽象库来抽象化上述内容。否则,在低级代码中,它看起来像:
// yes, we're not using pg_insert() $result = pg_query($db, "INSERT INTO foo (bar) VALUES (123) RETURNING foo_id"); $insert_row = pg_fetch_row($result); $insert_id = $insert_row[0];
$result = pg_execute($db, "INSERT INTO foo (bar) values (123);"); $insert_query = pg_query("SELECT lastval();"); $insert_row = pg_fetch_row($insert_query); $insert_id = $insert_row[0];
$insert_query = pg_query($db, "SELECT nextval('foo_seq');"); $insert_row = pg_fetch_row($insert_query); $insert_id = $insert_row[0]; $result = pg_execute($db, "INSERT INTO foo (foo_id, bar) VALUES ($insert_id, 123);");
最安全的选择是第三种方法,但这很笨拙。最干净的是第一个,但是我们需要运行最新的PostgreSQL。但是,大多数数据库抽象库尚未使用第一种方法。