currval尚未定义此会话,如何获得多会话序列?

时间:2012-09-18 16:46:00

标签: postgresql database-design auto-increment postgresql-8.4

我的目标是在表格中插入新行时自动插入主键字段。

如何在PostgreSQL中让一个序列从一个会话到另一个会话?

 doubleemploi@hanbei:/home/yves$ psql -d test
 Mot de passe : 
 psql (8.4.13)
 Saisissez « help » pour l''aide.

 test=> create sequence test001 start 10;
 CREATE SEQUENCE
 test=> select currval('test001');
 ERREUR:  la valeur courante (currval) de la séquence « test00 » n''est pas encore définie dans cette session
 --- current value not yet defined this session (???)
 test=> select setval('test001', 10);
 setval 
 --------
      10
 (1 ligne)

 test=> select currval('test00');
  currval 
 ---------
       10
 (1 ligne)

 test=> \q
 test@hanbei:/home/yves$ psql -d test
 Mot de passe : 
 psql (8.4.13)
 Saisissez « help » pour l''aide.

 test=> select currval('test001');
 ERREUR:  la valeur courante (currval) de la séquence « test00 » n''est pas encore définie dans cette session

4 个答案:

答案 0 :(得分:80)

currval将返回当前会话中为序列生成的最后一个值。因此,如果另一个会话为序列生成新值,您仍然可以检索由您的会话生成的最后一个值,从而避免错误。

但是,要在任何会话中获取最后生成的值,您可以使用以上内容:

SELECT last_value FROM your_sequence_name;

请注意,如果其他会话使用的值与未提交(或中止)的事务并且您使用此值作为参考,则可能会出错。通常人们只需要currval甚至是setval的返回。

答案 1 :(得分:5)

我会就此事给出实际答案。 我的程序和我的psql终端使用我的数据库服务器;所以有多个会话。目前我在我的psql终端:

fooserver=> select currval('fusion_id_seq');
ERROR:  currval of sequence "fusion_id_seq" is not yet defined in this session
fooserver=> select nextval('fusion_id_seq');
 nextval 
---------
  320032
(1 row)

fooserver=> select currval('fusion_id_seq');
 currval 
---------
  320032
(1 row)

看起来您只能看到自己会话中的值。这也会影响另一个会话的限制。这可能与服务器的多线程有关,以隔离不同的会话。计数器(psql中的串行)是一个共享对象。在我看来,只要计数器被正确锁定,该会话应该能够获得计数器的当前值,以确保只有一个线程(会话)可以递增它(原子操作)。但我在这里可能是错的(不是数据库服务器编写专家)。

答案 2 :(得分:2)

实际上 nextval 会推进序列并返回新值,这样就可以解答您的问题。

currval将返回最近使用nextval获取的指定序列的值(如果当前会话中没有使用nextval,则可能会失败。)

答案 3 :(得分:1)

This issue seems to be intermittent , For consistency use CTE to get inserted sequence for current session

WITH inserted AS ( INSERT INTO notifn_main (notifn_dt,stat_id) SELECT now(),22 FROM notifn RETURNING id ) SELECT id from inserted INTO tmp_id;