我的目标是在表格中插入新行时自动插入主键字段。
如何在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
答案 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;