在PostgreSQL事务块中获取ID

时间:2011-07-25 21:15:23

标签: sql postgresql transactions

我正在尝试将我应该全部或全部的所有交易包装到BEGINCOMMIT中,但我不确定如何在以下情况下执行此操作。< / p>

我有3个表,一个用于图像,一个用于albums,另一个用于它们之间的关系,即album_images。系统的工作方式是用户可以创建一个相册并在一次操作中用他的图像填充它。 SQL如下:

BEGIN;
  INSERT INTO albums [...];  -- Create a new album row
  SELECT id AS album_id FROM albums WHERE [...];  -- Get that rows ID
  -- Now use album_id in the next statement
  INSERT INTO album_images (album_id, image_id) [...];
COMMIT;

这可能是一个常见的问题,我只是不确定要搜索什么,我似乎也无法在文档中找到解决方案。

4 个答案:

答案 0 :(得分:6)

作为Cody提到的INSERT ... RETURNING子句的替代方法,您可以使用当前值与ID列关联的序列:

BEGIN;
  INSERT INTO albums [...];
  INSERT INTO album_images (currval('albums_id_seq'), image_id) [...];
COMMIT;

当为定义为serial的列自动创建序列时,这假定为Postgres的标准命名方案。

另一种选择 - 如果您只使用单个插入 - 是使用lastval()函数。然后,您甚至不需要将序列名称放入INSERT语句中:

BEGIN;
  INSERT INTO albums [...];
  INSERT INTO album_images (lastval(), image_id) [...];
COMMIT;

答案 1 :(得分:2)

Postgres提供了一个INSERT中使用的“RETURNING”子句,可以轻松地获取新创建的主键。

http://www.postgresql.org/docs/8.3/interactive/sql-insert.html

一些例子:http://6c62.net/blog/?p=48

答案 2 :(得分:0)

手动访问序列不理想

BEGIN;
  -- Create a new album row and hold onto the id
  WITH row as (INSERT INTO albums [...] RETURNING id AS album_id)
  -- Now use album_id in the next insert
  INSERT INTO album_images SELECT album_id, :image_id FROM row;
COMMIT;

returning实际上很有用,但是其他2个答案不知道/没有解释如何在此处应用

答案 3 :(得分:-1)

您可以将插入的行的ID设为

INSERT INTO albums [...] returning album_id;

这将在插入后返回album_id。