加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgreSQL函数用于最后插入的ID

发布时间:2020-12-13 16:56:54 所属栏目:百科 来源:网络整理
导读:如何获取插入表中的最后一个ID?在MS SQL中有SCOPE_IDENTITY()。 请不要建议使用这样的东西: select max(id) from table (tl; dr:goto选项3:INSERT with RETURNING) 回想一下,在postgresql中没有表的“id”概念,只是序列(通常但不一定用作代理主键的默
如何获取插入表中的最后一个ID?在MS SQL中有SCOPE_IDENTITY()。

请不要建议使用这样的东西:

select max(id) from table
(tl; dr:goto选项3:INSERT with RETURNING)

回想一下,在postgresql中没有表的“id”概念,只是序列(通常但不一定用作代理主键的默认值,具有SERIAL伪类型)。

如果你有兴趣获取一个新插入的行的id,有几种方法:

选项1:CURRVAL(<sequence name>);

例如:

INSERT INTO persons (lastname,firstname) VALUES ('Smith','John');
  SELECT currval('persons_id_seq');

序列的名称必须是已知的,它真的是随意的;在这个例子中,我们假设表的人有一个用SERIAL伪类型创建的id列。为了避免依赖于这个和感觉更干净,你可以改用pg_get_serial_sequence

INSERT INTO persons (lastname,'John');
  SELECT currval(pg_get_serial_sequence('persons','id'));

注意:currval()仅在同一会话中的INSERT(其已执行nextval())之后工作。

选项2:LASTVAL();

这类似于前面的,只是你不需要指定序列名称:它寻找最近修改的序列(总是在你的会话中,与上面相同的警告)。

CURRVAL和LASTVAL都是完全并发安全的。 PG中的序列的行为被设计为使得不同的会话不会干扰,所以没有竞争条件的风险(如果另一个会话在我的INSERT和我的SELECT之间插入另一行,我仍然得到正确的值)。

然而,他们有一个微妙的潜在问题。如果数据库有一些TRIGGER(或RULE),在插入人表,在其他表中做一些额外的插入…然后LASTVAL可能会给我们错误的值。该问题甚至可能发生在CURRVAL,如果额外的插入完成在同一人员表(这是不太常见,但风险仍然存在)。

选项3:INSERT带RETURNING

INSERT INTO persons (lastname,'John') RETURNING id;

这是最清洁,高效和安全的方式来获得id。它没有以前的任何风险。

缺点?几乎没有:您可能需要修改调用INSERT语句的方式(在最坏的情况下,也许您的API或DB层不希望INSERT返回值);它不是标准的SQL(谁关心);它可用自Postgresql 8.2(2006年12月…)

结论:如果可以,去选择3.在其他地方,喜欢1。

注意:如果您打算获取最后一个全局插入的id(不一定在会话中),所有这些方法都是无用的。为此,您必须从表中选择max(id)(当然,这不会从其他事务读取未提交的插入)。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读