什么是 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相关推荐

  1. MySQL5.7之Json Column和Generated Column使用介绍

    目录 前言 一.MySQL中的Generated Column列(计算列) 二.JSON字段相关查询 三.JSON字段相关写操作 四.JSON字段索引以及Generated字段 五.结束语 前言 My ...

  2. postgresql学习_在PostgreSQL中学习这些快速技巧

    postgresql学习 PostgreSQL is one of the most popular open source SQL dialects. One of its main advanta ...

  3. 插入,在PostgreSQL中重复更新吗?

    本文翻译自:Insert, on duplicate update in PostgreSQL? Several months ago I learned from an answer on Stac ...

  4. 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 ...

  5. PostgreSQL 中的引号与大小写

    单双引号 单引号用来标识实际的值,双引号用来标识表名(table name)或列名(column name)等数据库中存在的值. select "name" from " ...

  6. PostgreSQL中定时job执行(pgAgent)

    PostgreSQL中定时job执行 业务分析 近期项目需要定期清理数据库中的多余数据,即每月1号删除指定表中一年以上的数据.  初步分析这种定时job可以使用一下两种技术实现: Linux的cron ...

  7. PostgreSQL中生成的列

    目录 介绍 背景 PostgreSQL 12 与SQL Server计算列比较 那么,生成的列与带有DEFAULT子句的常规列有何不同? 局限性 其他注意事项 PostgreSQL 11.x及更高版本 ...

  8. PostgreSQL 中的单引号与双引号

    PostgreSQL 中的单引号与双引号 在pg中的sql,单引号用来标识实际的值,双引号用来标识表名(table name)或列名(column name)等数据库中存在的值. 如,执行一句quer ...

  9. Postgresql杂谈 04—Postgresql中的五种常规索引

    一.索引的分类 Postgresql中索引一共分为5种,每一种都有它合适的应用场景,我们在使用时要根据不同业务的特点,选择合适的索引,这样才能加快sql语句的查询效率.下面,我们将就每种不同的索引,介 ...

最新文章

  1. .net 怎么循环得到数组里的值_提升ML.NET模型的准确性
  2. nagios自定义监控API插件
  3. Linux shell 读取一行
  4. 暑假第六周总结(2018.8.13-8.19)
  5. 正式软件工作第一天————MVC、ext JS、和clsa
  6. 初识Hibernate 缓存
  7. 进程常用指令 (从创建到回收 包含守护)
  8. Java 8.if语句
  9. erlang的dict源码解析(1)
  10. C语言实现九九乘法表
  11. 基于marlin固件的SCARA机器人
  12. python魔方程序算法_《Python基础教程》第9章 魔方方法、属性和迭代器
  13. 达人评测 r7 7730U和R5 7530U选哪个好 锐龙r77730U和R57530U对比
  14. [思维模式-13]:《复盘》-1- “知”篇 - 认识复盘
  15. Docker Linux下安装配置及启动
  16. matlab地球月球卫星关系,Matlab 卫星绕地球旋转演示动画
  17. 大南湖地磅房升级需要改造哪些方面
  18. 定时器、Lambda表达式、Stream流
  19. 动态创建数组了解各种取值和取地址的问题以及感受内存地址
  20. 餐饮店如何在小红书上引流?小红书转化怎么样

热门文章

  1. 智慧灯杆市场调研分析
  2. CentOS7.3服务器内网离线部署docker和容器
  3. RS485 通信与 Modbus 协议
  4. IDA静态分析so文件(一)
  5. 蓝桥杯练习 字母图形
  6. linux 线程与进程的简单区别
  7. CATIA操作经典技巧问答
  8. zigbee协议栈学习(四)
  9. SWUST OJ 594: Maximum Tape Utilization Ratio
  10. [Python]获取2个字符串的最长公共子串