如何在 sql INSERT 期间自动生成 ID?

How to autogenerate ID during sql INSERT?

INSERT INTO table_having_pk SELECT * FROM table_without_pk;

两个 table 的架构相同,只是没有为 table_without_pk 设置主键约束。

问题:在复制过程中,第二个 table 的条目在 ID 中有 null,因此插入第一个 table 失败。

org.hibernate.engine.jdbc.spi.SqlExceptionHelper: SQL Error: 0, SQLState: 23502
org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ERROR: NULL-Value in Column ?id? violates Not-Null-Constraint

如何让第一个 table 在插入过程中自动生成 ID(只需将它们加起来)?

Postgres 9.x

在我的 @Entity class 中,ID 生成如下 table_having_pk:

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private long id;
create table twpk(a text);

insert into twpk values('a'), ('b'), ('c');

create temporary sequence mysequence;

create table twpk2 as
select nextval('mysequence'), a from twpk;

select * from twpk2

只需省略 id 列,它将自动为 serial 列生成。
您需要添加一个包含所有列的列列表 除了 id 列:

INSERT INTO table_having_pk (col1, col2, ...)
SELECT col1, col2, ... FROM table_without_pk;

如果您的列没有序列的默认值(如 serial 那样),您也可以从 both 中删除 id 列表格和:

INSERT INTO table_having_pk
SELECT * FROM table_without_pk;

然后添加一个serial列:

ALTER TABLE table_having_pk ADD COLUMN table_having_pk_id serial PRIMARY KEY;

号码是自动生成的,所以这需要一点时间。每一行都被重写。

如果您不想要 serial(或不能有),您可以即时生成数字:

INSERT INTO table_having_pk (id, col1, col2, ...)
SELECT row_number() OVER (), col1, col2, ...
FROM table_without_pk;