摘要:介绍CREATE TYPE语法可以在数据库中定义一种新的数据类型。

本文分享自华为云社区《GaussDB(DWS)数据类型之自定义数据类型(复合类型)》,作者: 清道夫。

CREATE TYPE语法可以在数据库中定义一种新的数据类型。

  • 复合类型 —— 实际上与表相同,但并不会创建一个实际的表。
  • 基本类型 —— 新的基本类型,需要指定对应的外部input及output函数。
  • shell类型 —— 占位符
  • 枚举类型 —— 一个非空字符串构成的标签列表

复合类型

语法

CREATE TYPE name AS
( [ attribute_name data_type [ COLLATE collation ] [, ... ] ] )

详解

1.首先创建一个新的复合类型包含两个INT4数据类型

postgres=# CREATE TYPE point_comlex AS (x INT, y INT);
CREATE TYPE

2.基于创建新的数据类型创建一个表

postgres=# CREATE TABLE position(no INT4, coordinate point_comlex)DISTRIBUTE BY ROUNDROBIN;
CREATE TABLE

3.查询数据

postgres=# SELECT * FROM position;
no | coordinate
----+------------
1 | (1,1)
(1 row) -- 注意:SELECT查询语句中不允许对复合类型的某一字段进行查询
postgres=# SELECT coordinate.x FROM position;
ERROR: missing FROM-clause entry for table "coordinate"
LINE 1: SELECT coordinate.x FROM position;
^
CONTEXT: referenced column: x

4.插入数据

-- 整行插入
postgres=# INSERT INTO position VALUES(1, (1, 1));
INSERT 0 1 -- 只插入某一个字段
postgres=# INSERT INTO position(coordinate.x) VALUES(2);
INSERT 0 1
postgres=# SELECT * FROM position;
no | coordinate
----+------------
1 | (1,1)
| (2,)
(2 rows)

5.更新数据

-- 按列更新
postgres=# UPDATE position SET coordinate=(10,20) WHERE no=1;
UPDATE 1
postgres=# SELECT * FROM position;
no | coordinate
----+------------
| (2,)
1 | (10,20)
(2 rows) -- 单字段更新
postgres=# UPDATE position SET coordinate.y=2 WHERE no is null;
UPDATE 1
postgres=# SELECT * FROM position;
no | coordinate
----+------------
1 | (10,20)
| (2,2)
(2 rows) postgres=# UPDATE position SET position.coordinate.y=3 WHERE no is null;
UPDATE 1
postgres=# SELECT * FROM position;
no | coordinate
----+------------
1 | (10,20)
| (2,3)
(2 rows)

彩蛋

到这基本就结束了,细心的小伙伴可能会问,如果表名、列名、字段名相同是否会有歧义呢,数据库又是如何处理歧义的?

-- 新建一个复合类型
postgres=# CREATE TYPE newtype AS(no INT, info text);
CREATE TYPE
-- 创建一个表,表名、列名均与复合类型中的字段名相同
postgres=# CREATE TABLE info(no INT, info newtype)DISTRIBUTE BY ROUNDROBIN;
CREATE TABLE
-- 插入一条数据
postgres=# INSERT INTO info VALUES(1, (1, 'MIKE'));
INSERT 0 1
-- 查询
postgres=# SELECT * FROM info;
no | info
----+----------
1 | (1,MIKE)
(1 row)

此时表名、列名与复合类型中的字段名均相同,那http://info.info既可以是表名.列名又可以使列名.字段名,实际上是什么呢?

postgres=# UPDATE info SET info.info='JACK' WHERE no=1;
NOTICE: update field 'info' of column 'info', though it's ambiguous.
UPDATE 1
postgres=# SELECT * FROM info;
no | info
----+----------
1 | (1,JACK)
(1 row)

通过执行的提示信息我们可以看出,数据库发现了歧义。而且最终更新的是列中的字段。

从这可以看出,对于有歧义的更新,数据库的处理是有优先级的定义的,此处是列名.字段名 > 表名.列名

此处还有一个疑问,那如果schema的名字也相同,数据库如何处理呢?

-- 创建SCHEMA
postgres=# CREATE SCHEMA info;
CREATE SCHEMA
-- 设置为当前SCHEMA
postgres=# SET CURRENT_SCHEMA=info;
SET
-- 创建复合类型
postgres=# CREATE TYPE newtype AS(no INT, info text);
CREATE TYPE
-- 创建与复合类型字段名相同的表名
postgres=# CREATE TABLE info(no INT, info newtype)DISTRIBUTE BY ROUNDROBIN;
CREATE TABLE
-- 插入数据
postgres=# INSERT INTO info VALUES(1, (1, 'MIKE'));
INSERT 0 1
-- 歧义场景更新,优先更新列中的字段
postgres=# UPDATE info SET info.info='JACK' WHERE no=1;
NOTICE: update field 'info' of column 'info', though it's ambiguous.
UPDATE 1
postgres=# SELECT * FROM info;
no | info
----+----------
1 | (1,JACK)
(1 row) -- info.info.info代表的是表名.列名.字段名
postgres=# UPDATE info SET info.info.info='TOM' WHERE no=1;
UPDATE 1
postgres=# SELECT * FROM info;
no | info
----+---------
1 | (1,TOM)
(1 row) -- info.info.no代表的也是表名.列名.字段名,此处有歧义但好像没提示,为什么呢?接着往下看
postgres=# UPDATE info SET info.info.no=2 WHERE no=1;
UPDATE 1
postgres=# SELECT * FROM info;
no | info
----+---------
1 | (2,TOM)
(1 row)
-- info.info.info.info更新报错,也就是说SET后不能使用schema名称,也就解释了上面的语句没有歧义提示
postgres=# UPDATE info SET info.info.info.info='JACK' WHERE no=1;
ERROR: cannot assign to field "info" of column "info" because its type text is not a composite type
LINE 1: UPDATE info SET info.info.info.info='JACK' WHERE no=1;
^
CONTEXT: referenced column: info

可以看出UDPATE的SET中不能出现schema,否则会报错

-- 创建一个新的表
postgres=# CREATE TABLE test(a INT)DISTRIBUTE BY ROUNDROBIN;
CREATE TABLE
-- 更新时指定schema
postgres=# UPDATE test SET info.test.a=1;
ERROR: column "info.test" of relation "test" does not exist
LINE 1: UPDATE test SET info.test.a=1;
^

从上述报错提示可以看出,数据库将SET之后的info.test认为是test表的一列。而表定义中没有,因此必然报错。

想了解GuassDB(DWS)更多信息,欢迎微信搜索“GaussDB DWS”关注微信公众号,和您分享最新最全的PB级数仓黑科技,后台还可获取众多学习资料哦~

点击关注,第一时间了解华为云新鲜技术~

基于CREATE TYPE语法自定义新数据类型的更多相关文章

  1. CREATE TYPE - 定义一个新的数据类型

    SYNOPSIS CREATE TYPE name AS ( attribute_name data_type [, ... ] ) CREATE TYPE name ( INPUT = input_ ...

  2. 转载:oracle 自定义类型 type / create type

    标签:type create oracle object record 一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarc ...

  3. oracle 自定义类型 type / create type

    一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarchar2. 2.数值类型.如:int.number(p,s).integ ...

  4. MySQL create table 语法

    MySQL中create table语句的基本语法是: CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name     [(create_definitio ...

  5. CREATE FUNCTION - 定义一个新函数

    SYNOPSIS CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] ) RETURNS rettype { LANGUAGE lang ...

  6. 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)

    在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...

  7. 基础篇之 Create Type

    Create Type 的话呢,是创建一个自定义的数据类型,等于说为常用的数据类型建造一个别名的样纸.然后就可以通用当前数据库的当前架构.(当然了,一般来说我们都是使用dbo架构,所以都会无事前面那个 ...

  8. type和create type

    type和create type 异同点:      create type 可在库中生成一个长期有效的自定义类型对象,而type作用域仅限于语句块中:      两者都可以自定义数据类型: 各种ty ...

  9. 【转】SQL Server 2008 新数据类型

    概览: 新日期和时间数据类型 代表在层次结构中的位置 用于处理空间数据的两种模型 在全球经济环境下开展业务这一趋势越来越要求各公司使用新型的数据.应用程序以及复杂的计算.SQL Server 2008 ...

  10. CREATE OPERATOR - 定义一个新的操作符

    SYNOPSIS CREATE OPERATOR name ( PROCEDURE = funcname [, LEFTARG = lefttype ] [, RIGHTARG = righttype ...

随机推荐

  1. CF1190C Tokitsukaze and Duel

    搬运一下本喵的 lg 博客 qwq 详细讲一下如何判定后手能否获胜,对其他题解做个补充.(蒟蒻的我想了好久来着 此题的关键点在于可以重复上一个人的操作使局面保持不变. 考虑先手的获胜条件,由上一段可知 ...

  2. APP攻防--安卓逆向&数据修改&逻辑修改&视图修改

    APP攻防--安卓逆向&数据修改&逻辑修改&视图修改 @ 目录 APP攻防--安卓逆向&数据修改&逻辑修改&视图修改 工具集 apk目录意义 逆向数据修 ...

  3. 把工单历史表中的数据,按照工单进行分类,每一批工单的数据放在同一个 key 中

    /** * 把工单历史表中的数据,按照工单进行分类,每一批工单的数据放在同一个key中 * 将对象列表按名称分类成 Map(分类名必与对象的某 get 方法的后的名一致<如:get(name) ...

  4. Python Web UI自动化报错 :ResourceWarning: Enable tracemalloc to get the object allocation traceback

    ResourceWarning资源警告解决方案 原因:在执行线性脚本完毕时,没有及时释放相应资源,导致内存堆积,从而造成内存溢出(如关闭浏览器等操作),此时,Python将会做出提醒: 在百度吸取 网 ...

  5. 本地MQTT协议消息服务远程连接教程介绍

    Mosquitto是一个开源的消息代理,它实现了MQTT协议版本3.1和3.1.1.它可以在不同的平台上运行,包括Windows.Linux.macOS等.mosquitto可以用于物联网.传感器.移 ...

  6. 计算机网络之防火墙和Wlan配置

    一.防火墙 防火墙(firewall)是一种安全设备,它的位置一般处于企业网络边界与外网交界的地方,用于隔离不信任的数据包 准确点讲,它就是隔离外网和内网的一道屏障,用于保护内部资源信息安全的一种策略 ...

  7. iOS之H5与原生交互

    少年易学老难成,一寸光阴不可轻. 1. 利用UIWebView交互   iOS7之前通过UIWebView相关代理方法进行通信.原理:通过协议拦截实现h5对原生的调用,通过直接调用js来实现原生对h5 ...

  8. 关于Delphi

    # 关于Delphi ··Delphi中使用的面向对象pascal编程语言. ··Pascal语言最初由瑞士苏黎士理工学院的尼古拉斯-沃斯(Niklaus Wirth)教授在1971年设计. ··19 ...

  9. 【死亡小学期第二章:没头脑和不高兴】数据库jdbc系统

    自己做一个JDBC的数据库系统,因为这个一直做嘛,所以很简单啦,并没有想提高技术拔拔高啥的,就想做一个简单的,然后自己感兴趣的内容.让自己快乐快乐那才叫做意义~~~~~~~kkkk 学到的东西: 展示 ...

  10. 33. 干货系列从零用Rust编写正反向代理,关于HTTP客户端代理的源码实现

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...