Postgresql INSERT - 自动获取下一个ID?

时间:2017-08-03 11:21:50

标签: postgresql intellij-idea

我正在使用IntelliJ和数据库工具。我有一些数据的问题,所以我删除了一行,但后来又想添加几个...

我使用了克隆选项:

enter image description here

然后我修改了我的值并点击commit按钮。

但是,插入失败并显示错误:

  

错误:重复键值违反唯一约束“主键some_table”详细信息:键(id)=(58)已存在。

然后我通过控制台尝试并手动插入,但我得到了同样的错误。 每次我这样做,id增加...我有成千上万的记录,所以我不能一直点击,直到我的手指断开。

这就是id的样子(创建表时):

id bigserial not null constraint "Primary Key some_table"
primary key

当我尝试修改表格时,我看到id的默认值设置如下:

nextval('some_table_id_seq'::regclass)

我试过了:

INSERT INTO some_table (id,...columns..) VALUES (DEFAULT,...columns...);

INSERT INTO some_table (...columns..) VALUES (...columns...);

但我得到同样的错误......

我意识到我可以执行一些like运行查询以获取MAX id然后然后执行我的插入操作,但这对我来说似乎有点荒谬。

如何定制我的INSERT以便自动获取新的/下一个id

例如,MSSQL已使用newid()自动为您处理此问题。

更新

好的,我弄清楚问题是什么......

我已经先克隆了表,然后还克隆了序列。这就是导致问题的原因:id some_table列中的默认值是使用来自OLD克隆表的序列......

我修改了序列名称以使用新序列,并且它有效。

此外,在进行插入时,您可以替换使用:

INSERT INTO some_table (id,...columns..) VALUES (nextval('some_table_id_seq'::regclass),...columns...);

自动生成id(与引用DEFAULT相同)

谢谢大家的帮助。获得的经验:不要克隆表格;不要偷懒。

5 个答案:

答案 0 :(得分:1)

您可以跳过插入列列表中的列,也可以使用DEFAULT关键字,如下所示:

t=# create table i (i bigserial, t text);
CREATE TABLE
Time: 99.579 ms
t=# insert into i (t) select null;
INSERT 0 1
Time: 75.390 ms
t=# insert into i values(DEFAULT,null);
INSERT 0 1
Time: 58.365 ms
t=# select * from i;
 i | t
---+---
 1 |
 2 |
(2 rows)

答案 1 :(得分:0)

如果序列与基础数据不同步(由于手动输入的记录或来自错误序列的ID),您可以使用以下命令重置它们:

Dim oOlApp As Object, objNmSpc As Object, ofldr As Object
Dim myCopiedItem As Outlook.MailItem
Dim myNewFolder  As String

Set oOlApp = GetObject(, "Outlook.Application")
If Err.Number <> 0 Then
    Set oOlApp = CreateObject("Outlook.Application")
End If
Err.Clear

Set objNmSpc = oOlApp.GetNamespace("MAPI")
Set ofldr = objNmSpc.PickFolder
If Not ofldr Is Nothing Then MsgBox ofldr

Dim oItem As Object
For Each oItem In ofldr.Items
    If oOlApp.ActiveExplorer.Selection.Item(1) = True Then
        oItem.SaveAs Sheet1.Range("V5").Value & oItem.Subject & ".msg", olMSG
        match.Offset(, 7).Value = oItem.SenderName & "-" & oItem.Subject & "-" & oItem.ReceivedTime
        match.Offset(, 8).Value = VBA.Environ("Username") & "- " & VBA.Now
        Exit Sub
    End If
Next oItem

这只是在当前表中找到最高ID,然后将序列更新为下一个可用值。

文档:https://www.postgresql.org/docs/current/static/functions-sequence.html

答案 2 :(得分:0)

好的,我知道问题出在哪里...

先前克隆了表,然后克隆了该序列。这就是造成此问题的原因:id的{​​{1}}列中的默认值使用的是OLD克隆表中的序列...

我修改了序列名称以使用新的序列,并且有效。

此外,在插入时,您可以替换使用:

some_table

自动生成INSERT INTO some_table (id,...columns..) VALUES (nextval('some_table_id_seq'::regclass),...columns...); (与引用id相同)

感谢大家的帮助。经验教训:不要克隆表;不要偷懒。

答案 3 :(得分:0)

如果您知道它应该是什么,还有另一种方法可以将其重置为您想要的值,这就是以下内容:“alter sequence schema.table_id_seq restart with xx”(其中 xx 是下一个可用数字)。这适用于 12.x 和 13.x,架构是架构的名称,表是表的名称!

答案 4 :(得分:-1)

您可以尝试一下,

 cur.execute("SELECT * FROM Employee_Activity")
    rows = cur.fetchall()
    for row in rows:
       val_id=(row[0])
    val_id+=1 

val_id可以自动获取并递增