postgre报错:RETURNING “id“ was aborted: ERROR: null value in column “id“ violates not-null constraint
我在使用 postgre 插入数据的时候报了一个错:RETURNING "id" was aborted: ERROR: null value in column "id" violates not-null constraint表的创建 sql 语句如下:CREATE TABLE city(id int8 PRIMARY KEY NOT NULL ,name varchar(30) NOT NU
我在使用 postgre 插入数据的时候报了一个错:
RETURNING "id" was aborted: ERROR: null value in column "id" violates not-null constraint
表的创建 sql 语句如下:
CREATE TABLE city(
id int8 PRIMARY KEY NOT NULL ,
name varchar(30) NOT NULL ,
gov_area VARCHAR(100) NOT NULL
);
后来我对比了其他表的接口,返现 id 设置这里缺少了这个配置:
其他表多了这个配置,例如 student 表:
nextval('student_id_seq'::regclass)
我不管三七二十一复制这个配置到我创建的表里面,发现表可以插入数据了,但是奇怪的是,id 是自增的,但是不是从 1 开始自增,而是从 2215817 自增。之前用 mysql 设置 int 类型的 id 自增的时候根本没这么出现过,我记得 mysql 表 int 自增只需要配置(甚至直接勾选自增即可):
UNSIGNED AUTO_INCREMENT
后来我上网查了一下,发现 postgre 没有这样的配置,但是可以在 id 这个字段上设置序列和索引来实现 id 的自增。
创建序列:
CREATE SEQUENCE city_id_seq;
这个序列一般命名为 “表名_id_seq””
然后将这个序列指定为 id 使用,直接到 navicat 配置:
也可以到使用 sql 配置:
CREATE UNIQUE INDEX city_id_seq ON city ( id );
PS: PostgreSQL 提供三种序列伪类型,分别为SMALLSERIAL, SERIAL, BIGSERIAL,对应范围如下:
类型 | 长度 | 范围 |
---|---|---|
smallserial | 2 bytes | 1 to 32,767 |
serial | 4 bytes | 1 to 2,147,483,647 |
bigserial | 8 bytes | 1 to 922,337,2036,854,775,807 |
这三种类型都可以用于直接定义序列,用于 id 唯一键
经常用的类型是 serial,将 id 的类型为 serial 时,PostgreSQL将执行下列步骤:
- 创建序列对象并设置下一个生成值作为列的缺省值;
- 给对应列增加NOT NULL约束,因为序列总是生成一个整数值,不能为null值;
- 赋值序列的拥有者给id列,因此当id列或表被删除时,序列对象自动被删除
例如上面的创建表的 sql 可以改成:
CREATE TABLE city(
id serial ,
name varchar(30) NOT NULL ,
gov_area VARCHAR(100) NOT NULL
);
这样就会自动创建 city_id_seq 的序列,不用再跟上面我一样再去创建序列并赋予给 id 使用,postgre 都已经帮我们处理好了,这个 sql 也相当于下面的语句:
CREATE SEQUENCE city_id_seq;
CREATE TABLE city(
id integer PRIMARY KEY NOT NULL DEFAULT nextval('city_id_seq'),
name varchar(30) NOT NULL ,
gov_area VARCHAR(100) NOT NULL
);
最后,我发现删除这个表后,创建的序列也会被删除,查看序列的下一个值:
SELECT nextval('city_id_seq');
更多推荐
所有评论(0)