MUY*_*ium 29 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
Run Code Online (Sandbox Code Playgroud)
Mat*_*sOl 89
在currval
将返回在当前会话中序列生成的最后一个值.因此,如果另一个会话为序列生成新值,您仍然可以检索由您的会话生成的最后一个值,从而避免错误.
但是,要获得任何会话的最后生成值,您可以使用以上内容:
SELECT last_value FROM your_sequence_name;
Run Code Online (Sandbox Code Playgroud)
请注意,如果其他会话使用的值与未公开(或中止)的事务并且您使用此值作为参考,则可能会出错.一般人们只需要currval
甚至回归setval
.
Erw*_*ter 15
这可能比你想象的要简单......
我的目标是在表中插入新行时自动插入主键字段.
只需设置列的默认值:
ALTER TABLE tbl ALTER COLUMN tbl_id SET DEFAULT nextval('my_seq'::regclass);
Run Code Online (Sandbox Code Playgroud)
或者更简单,创建具有serial
主键类型的表格开头:
CREATE TABLE tbl(
tbl_id serial PRIMARY KEY
,col1 txt
-- more columns
);
Run Code Online (Sandbox Code Playgroud)
它创建一个专用序列并自动设置tbl_id的默认值.
这种方式tbl_id
被分配从附加序列的下一个值,如果自动你不提它INSERT
.适用于任何会话,并发或不兼容.
INSERT INTO tbl(col1) VALUES ('foo');
Run Code Online (Sandbox Code Playgroud)
如果你想让新的tbl_id
回来做一些事情:
INSERT INTO tbl(col1) VALUES ('foo') RETURNING tbl_id;
Run Code Online (Sandbox Code Playgroud)
对于这个问题,我将给出一个实际的答案。我的程序和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)
Run Code Online (Sandbox Code Playgroud)
看来您只能在自己的会话中看到这些值。这也将影响另一个会话的周期。这可能与服务器的多线程隔离不同的会话有关。计数器(在psql中为串行)是一个共享库。我认为,只要正确锁定计数器以确保只有一个线程(会话)可以递增计数器(原子操作),那么该会话就应该能够获取计数器的当前值。但是我在这里可能是错的(不是数据库服务器编写专家)。