PostgreSQL中的GENERATED COLUMN
什么是 GENERATED COLUMN
GENERATE COLUMN 是一个在 CREATE TABLE 时指定的标识列(特征列)。该列将会附着一个隐藏的序列,并且在插入数据时以默认的隐藏序列为数据行进行插入。该列默认约束为 NOT NULL 约束。该列后有可选 GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence _ options ) ]关键字。如果使用 ALWAYS 关键字,当在使用 INSERT 语句时接受 OVERRIDING SYSTEM VALUES 语句。如果指定 BY DEFAULT ,则用户指定的值优先。
该特性是在 PostgreSQL V10 版本中推出,属于约束的一种,实际上是自动为列分配一个唯一的值。类似整形序列加非空约束,但是又可以以用户指定的方式进行数据插入。
语法
列名 数据类型 GENERATED { ALWAYS | BY DEFAULT } AS IDENTIFY [ ( sequence_option ) ]
语法解释:
数据类型: 通常是整型的一种[ int2 | int4 | int8 | smallint | int | bigint ]
GENERATED ALWAYS: PostgreSQL 总会为列生成一个唯一的值,如果尝试以 INSERT 或者 UPDATE 在 GENERATED ALWAYS AS IDENTIFY 列上进行插入数据或者更新时, PostgreSQL 将会报错。
GENERATED BY DEFAULT: PostgreSQL 将会生成一个标识列,但是如果尝试以 INSERT 或者 UPDATE 对该列进行插入或者更新时,PostgreSQL 将会使用指定的值来替代系统生成的值。
PostgreSQL 允许在一个表中有多个标识列,GENERATED AS IDENTIFY 在数据库内部使用的是 SEQUENCE 对象
使用示例
GENERATED ALWAYS
创建表
postgres=# CREATE TABLE tab_product
(id int generated always as identity,product_name varchar(80),product_date date,product_vendor varchar(80)
);
CREATE TABLE
插入数据
postgres=# INSERT INTO TAB_PRODUCT ( PRODUCT_NAME , PRODUCT_DATE , PRODUCT_VENDOR)
VALUES ( 'HuaWei' ,'2021-01-01' ,'HuaweiTec') ;
INSERT 0 1
查看数据
postgres=# SELECT * FROM tab_product;id | product_name | product_date | product_vendor
----+--------------+--------------+----------------1 | HuaWei | 2021-01-01 | HuaweiTec
(1 row)
使用用户指定id将会报错
如果在 GENERATED ALWAYS 约束下,用户在 INSERT 或者 UPDATE 语句中指定自定义值将会报错。如下:
postgres=# INSERT INTO tab_product
VALUES(2,'Mate','2021-02-03','HuaWeiTec');
ERROR: cannot insert into column "id"
DETAIL: Column "id" is an identity column defined as GENERATED ALWAYS.
HINT: Use OVERRIDING SYSTEM VALUE to override.
解决方法
在语句中使用 OVERRIDING SYSTEM VALUE 语句,如下:
postgres=# INSERT INTO tab_product
OVERRIDING SYSTEM VALUE
VALUES(2,'Mate','2021-02-03','HuaWeiTec');
INSERT 0 1
再次查看数据
postgres=# SELECT * FROM tab_product;id | product_name | product_date | product_vendor
----+--------------+--------------+----------------1 | HuaWei | 2021-01-01 | HuaweiTec2 | Mate | 2021-02-03 | HuaWeiTec
(2 rows)
GENERATED BY DEFAULT AS IDENTITY
创建表
postgres=# DROP TABLE IF EXISTS tab_product;
DROP TABLE
postgres=# CREATE TABLE tab_product
(id int generated by default as identity,product_name varchar(80),product_date date,product_vendor varchar(80)
);
CREATE TABLE
插入数据
postgres=# INSERT INTO tab_product ( PRODUCT_NAME , PRODUCT_DATE , PRODUCT_VENDOR)
VALUES ( 'HuaWei' ,'2021-01-01' ,'HuaweiTec') ;
INSERT 0 1
用户指定数据插入
在 GENERATED BY DEFAULT AS IDENTITY 语句中,用户指定值将会正常运行,如下:
postgres=# INSERT INTO tab_product
VALUES(2,'Mate','2021-02-03','HuaWeiTec');
INSERT 0 1
查看数据
postgres=# SELECT * FROM tab_product;id | product_name | product_date | product_vendor
----+--------------+--------------+----------------2 | Mate | 2021-02-03 | HuaWeiTec
(1 row)
可选序列参数
由于 GENERATED AS IDENTITY 内部使用 SEQUENCE 对象,因此,可以在列级别指定序列中使用的参数。如指定起始值和步长值,最大值,最小值,是否可以循环,是否有缓存等等,如下:
postgres=# DROP TABLE IF EXISTS tab_product;
DROP TABLE
postgres=# CREATE TABLE tab_product
(id int generated by default as identity(start with 1 increment by 2 minvalue 1 maxvalue 10 cycle),product_name varchar(80),product_date date,product_vendor varchar(80)
);
CREATE TABLE
插入数据
postgres=# INSERT INTO tab_product ( PRODUCT_NAME , PRODUCT_DATE , PRODUCT_VENDOR)
VALUES ( 'HuaWei' ,'2021-01-01' ,'HuaweiTec') ;
INSERT 0 1
postgres=# INSERT INTO tab_product ( PRODUCT_NAME , PRODUCT_DATE , PRODUCT_VENDOR)
VALUES ( 'Mate' ,'2021-03-01' ,'HuaweiTec') ;
INSERT 0 1
查看数据
postgres=# SELECT * FROM tab_product;id | product_name | product_date | product_vendor
----+--------------+--------------+----------------1 | HuaWei | 2021-01-01 | HuaweiTec3 | Mate | 2021-03-01 | HuaweiTec
(2 rows)
可以看到,插入的第二条数据以指定的序列的参数递增。
修改 identity 列
postgres=# \d tab_product;Table "public.tab_product"Column | Type | Collation | Nullable | Default
----------------+-----------------------+-----------+----------+----------------------------------id | integer | | not null | generated by default as identityproduct_name | character varying(80) | | | product_date | date | | | product_vendor | character varying(80) | | | postgres=# ALTER TABLE tab_product
ALTER COLUMN id SET GENERATED ALWAYS;
ALTER TABLE
postgres=# \d tab_productTable "public.tab_product"Column | Type | Collation | Nullable | Default
----------------+-----------------------+-----------+----------+------------------------------id | integer | | not null | generated always as identityproduct_name | character varying(80) | | | product_date | date | | | product_vendor | character varying(80) | | |
移除表中列的 IDENTITY 属性
postgres=# \d tab_productTable "public.tab_product"Column | Type | Collation | Nullable | Default
----------------+-----------------------+-----------+----------+------------------------------id | integer | | not null | generated always as identityproduct_name | character varying(80) | | | product_date | date | | | product_vendor | character varying(80) | | | postgres=# ALTER TABLE tab_product
postgres-# ALTER COLUMN id
postgres-# DROP IDENTITY IF EXISTS;
ALTER TABLE
postgres=# \d tab_product Table "public.tab_product"Column | Type | Collation | Nullable | Default
----------------+-----------------------+-----------+----------+---------id | integer | | not null | product_name | character varying(80) | | | product_date | date | | | product_vendor | character varying(80) | | |
可以看到,在移除表中列具有的 IDENTITY 属性后,该列的约束仅仅剩下 NOT NULL 。
PostgreSQL中的GENERATED COLUMN相关推荐
- MySQL5.7之Json Column和Generated Column使用介绍
目录 前言 一.MySQL中的Generated Column列(计算列) 二.JSON字段相关查询 三.JSON字段相关写操作 四.JSON字段索引以及Generated字段 五.结束语 前言 My ...
- postgresql学习_在PostgreSQL中学习这些快速技巧
postgresql学习 PostgreSQL is one of the most popular open source SQL dialects. One of its main advanta ...
- 插入,在PostgreSQL中重复更新吗?
本文翻译自:Insert, on duplicate update in PostgreSQL? Several months ago I learned from an answer on Stac ...
- Cause: org.postgresql.util.PSQLException: ERROR: column province_id does not exist
数据库中的表bs_province如图所示: SQL语句: select PROVINCE_ID, PROVINCE_CODE, PROVINCE_NAME, SHORT_NAME, LNG, LAT ...
- PostgreSQL 中的引号与大小写
单双引号 单引号用来标识实际的值,双引号用来标识表名(table name)或列名(column name)等数据库中存在的值. select "name" from " ...
- PostgreSQL中定时job执行(pgAgent)
PostgreSQL中定时job执行 业务分析 近期项目需要定期清理数据库中的多余数据,即每月1号删除指定表中一年以上的数据. 初步分析这种定时job可以使用一下两种技术实现: Linux的cron ...
- PostgreSQL中生成的列
目录 介绍 背景 PostgreSQL 12 与SQL Server计算列比较 那么,生成的列与带有DEFAULT子句的常规列有何不同? 局限性 其他注意事项 PostgreSQL 11.x及更高版本 ...
- PostgreSQL 中的单引号与双引号
PostgreSQL 中的单引号与双引号 在pg中的sql,单引号用来标识实际的值,双引号用来标识表名(table name)或列名(column name)等数据库中存在的值. 如,执行一句quer ...
- Postgresql杂谈 04—Postgresql中的五种常规索引
一.索引的分类 Postgresql中索引一共分为5种,每一种都有它合适的应用场景,我们在使用时要根据不同业务的特点,选择合适的索引,这样才能加快sql语句的查询效率.下面,我们将就每种不同的索引,介 ...
最新文章
- .net 怎么循环得到数组里的值_提升ML.NET模型的准确性
- nagios自定义监控API插件
- Linux shell 读取一行
- 暑假第六周总结(2018.8.13-8.19)
- 正式软件工作第一天————MVC、ext JS、和clsa
- 初识Hibernate 缓存
- 进程常用指令 (从创建到回收 包含守护)
- Java 8.if语句
- erlang的dict源码解析(1)
- C语言实现九九乘法表
- 基于marlin固件的SCARA机器人
- python魔方程序算法_《Python基础教程》第9章 魔方方法、属性和迭代器
- 达人评测 r7 7730U和R5 7530U选哪个好 锐龙r77730U和R57530U对比
- [思维模式-13]:《复盘》-1- “知”篇 - 认识复盘
- Docker Linux下安装配置及启动
- matlab地球月球卫星关系,Matlab 卫星绕地球旋转演示动画
- 大南湖地磅房升级需要改造哪些方面
- 定时器、Lambda表达式、Stream流
- 动态创建数组了解各种取值和取地址的问题以及感受内存地址
- 餐饮店如何在小红书上引流?小红书转化怎么样