yxh1122

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

有时候导入一些数据后,再执行插入时会遇到:

    PGError: ERROR:  duplicate key value violates unique constraint "users_pkey"  问题。
这时需要再设置sequency。

方法如下:

Sql代码  收藏代码
  1. select setval('users_id_seq', (select max(id) + 1 from users));  

 

serial 类型实际上就是 int4, 只不过其默认值是从一个 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 可以设置为 truefalse。如果你把它设置为 false,那么下一次 nextval 将返回这里声明的数值,而从随后的 nextval 才开始递增该序列。 比如

SELECT setval('foo', 42);          下次nextval将返回 43
SELECT setval('foo', 42, true);     和上面一样
SELECT setval('foo', 42, false);    下次nextval将返回 42
posted on 2013-01-16 16:48  .NET易拉罐  阅读(6205)  评论(0)    收藏  举报