有时候导入一些数据后,再执行插入时会遇到:
PGError: ERROR: duplicate key value violates unique constraint "users_pkey" 问题。
这时需要再设置sequency。
方法如下:
- select setval('users_id_seq', (select max(id) + 1 from users));
serial 类型实际上就是 int4, 只不过其默认值是从一个 sequence 中取.
当表刚建立的时候,sequence 的值还是 1, 只有不断调用 sequence 的
nextval 函数才能够使 sequence 依次增长.
但是, 你的表中的数据是从别处导入的, 其 id 值已经占据了后面的数值,
当新插入记录的时候, 从 sequence 得到的值就可能和某一条已经存在的记录冲突.
当表刚建立的时候,sequence 的值还是 1, 只有不断调用 sequence 的
nextval 函数才能够使 sequence 依次增长.
但是, 你的表中的数据是从别处导入的, 其 id 值已经占据了后面的数值,
当新插入记录的时候, 从 sequence 得到的值就可能和某一条已经存在的记录冲突.
现在应该做的就是
select
setval('trn_staff_seq_seq', (select max(seq)+1 from
trn_staff));
把相应的 sequence 的值设置成表中最大 id 值加 1.
附:
序列函数
| 函数 | 返回类型 | 描述 |
|---|---|---|
nextval(regclass) |
bigint | 递增序列并返回新值 |
currval(regclass) |
bigint | 返回最近一次用nextval获取的指定序列的数值 |
lastval() |
bigint | 获取最近一次用 nextval 拿到的数值 |
setval(regclass,
bigint) |
bigint | 设置序列的当前数值 |
setval(regclass,
bigint, boolean) |
bigint | 设置序列的当前数值以及 is_called 标志 |
nextval-
递增序列对象到它的下一个数值并且返回该值。这个动作是自动完成的: 即使多个会话并发运行
nextval,每个进程也会安全地收到一个唯一的序列值。 currval-
在当前会话中返回最近一次
nextval抓到的该序列的数值。(如果在本会话中从未在该序列上调用过nextval,那么会报告一个错误。)请注意因为此函数返回一个会话范围的数值, 它也能给出一个可预计的结果,可以判断其它会话是否执行过nextval。 lastval-
返回当前会话里最近一次
nextval返回的数值。 这个函数等效于currval,只是它不用序列名位参数, 它抓取当前会话里面最近一次nextval使用的序列。 如果当前会话还没有调用过nextval,那么调用lastval是会报错的。 setval-
重置序列对象的计数器数值。双参数的形式设置序列的 last_value 字段为声明数值并且将其 is_called 字段设置为 true,表示下一次
nextval将在返回数值之前递增该序列。在三参数形式里,is_called 可以设置为 true 或 false。如果你把它设置为 false,那么下一次nextval将返回这里声明的数值,而从随后的nextval才开始递增该序列。 比如SELECT setval('foo', 42); 下次nextval将返回 43 SELECT setval('foo', 42, true); 和上面一样 SELECT setval('foo', 42, false); 下次nextval将返回 42

浙公网安备 33010602011771号