• 1.集合类型
    • 1.1关联数组
    • 1.2嵌套表
    • 1.3 可变长的数组
  • 2.声明集合类型
    • 2.1声明关联数组
    • 2.2声明嵌套表
    • 2.3声明VARRAY
  • 3.集合变量的声明和初始化
    • 3.1集合变量的声明
    • 3.2集合变量的初始化
    • 3.2.1通过构造函数的显示初始化
    • 3.2.2直接赋值时的隐式初始化
    • 3.2.3通过FETCH操作的隐式初始化
    • 3.2.4通过BULK COLLECT语句的隐式初始
  • 4.集合方法
  • 5.集合类型对比
  • 6.集合示例
    • 6.1关联数组示例
    • 6.2嵌套表示例
    • 6.3VARRAY实例

昨天才知道oracle数据库中也有集合类型,废话不多少,直接上文。

所谓集合是一种类似于列表或者一维数组的数据结构。PL/SQL提供了三种集合类型:关联数据组(索引表),嵌套表和VARRAY(可变长数组)。

1.集合类型

1.1关联数组

关联数组(也称为索引表)是一组键值对。每个密钥都是唯一的,并且被用于定位相应的值。键可以是整数或字符串。只能用于PL/SQL环境。

1.2嵌套表

从概念上讲,嵌套表像一个元素数量任意的一维数组。

在数据库中,嵌套表是存储一组值的列类型,数据库存储嵌套表的行是没有特定顺序的。当你从数据中提取嵌套表到PL/SQL变量时,该行给出连续从1开始的下标。通过这些类似数组下标访问独立的行。

嵌套表不同于数组的重要方面:

数组需要声明元素的个数,而嵌套表不需要。嵌套表的大小可以动态增加。数组总是密集的,嵌套表刚开始是密集的,但是后面有可能会变成稀疏的。因为你会从嵌套表中删除元素。

1.3 可变长的数组

可变长的数组是一个VARRAY数据类型的集合。当你声明VARRAY类型的时候,就必须指定同时指定它能够包含的最大元素个数。VARRAY可以包含可变数据的元素,从零到最大值。VARRAY索引有一个固定定的下限1和一个可扩展的上限。和嵌套表类型一样的是,它们都可以用于PL/SQL和数据库。但是和嵌套表不一样的是,在向VARRAY中保存数据或者提取数据时,它的元素是有序的。

2.声明集合类型

在使用一个集合之前,我们必须先声明它。有两种方法可以申明一个集合类型:

通过TYPE语句在一个PL/SQL程序中声明集合类型。通过CREATE TYPE语句在数据中定义一个嵌套表或者VARRAY类型,这个类型就是一个模式级别的对象。这种类型就可以用作数据库表的列的数据类型,可以用作对象类型的属性,也可以用于声明PL/SQL变量。

2.1声明关联数组

关联数组的TYPE语句的语法如下:

TYPE table_type_name IS TABLE OF datatype [ NOT NULL] INDEX BY index_type;

其中:

table_type_name是你所创建的集合类型的名字,datatype是集合中唯一一列的数据类型,index_type是用来组织集合内容的索引的数据类型。而集合唯一以列的数据类型可以是下面这些:

标量数据类型:任何被PL/SQL支持的标量数据类型,比如VARCHAR2,CLOB,POSITIVE,DATE,或者BOOLEAN。锚定数据类型:这种数据类型是从一个数据库表的列,之前已经定义的变量或者带有%TYPE属性的游标表达式推导出来的数据类型。我们也可以定义用%ROWTYPE声明或者根据一个用户定义的记录类型来定义一个记录的集合。复杂的数据类型:从Oracle 9i数据库R2版本开始,你也可以把对象类型和集合类型作为集合的数据类型。
集合语法中的index_type定义索引下标的数据类型。在Oracle 9i数据库版本R2之前,只能是INDEX BY PLS_INTEGER。从Oracle 9i数据库版本R2开始,INDEX BY的数据类型可以是BINARY_INTEGER、及它的子类型、VARCHAR2(N)或者VARCHAR2列或变量的%TYPE锚定类型。

2.2声明嵌套表

可以数据库内或者PL/SQL代码块中声明嵌套表类型。

在数据库内创建一个嵌套表类型:

CREATE [OR REPLACE] TYPE type_name AS | IS TABLE OF element_datatype [ NOT NULL ];

删除数据库内的嵌套表类型:

DROP TYPE type_name [FORCE];

在PL/SQL中声明一个嵌套表类型:

TYPE type_name IS TABLE OF element_datatype [ NOT NULL ];

其中:

OR REPLACE:允许我们重创建一个已经存在的类型。通过在语法中加上REPLACE的方式来重建类型,而不是先删除后再重新创建,可以把所有已经授予的权限都完整的保留下来。type_name:一个合法的SQL或者PL/SQL标志符。这也是我们以后在声明变量或者列时会用到的标识符。element_datatype:这是集合元素的数据类型。集合内所有元素都是一种类型的,可以是大部分标量数据类型、对象类型、或者REF对象类型。如果集合的元素是对象,对象类型本身不能再带有一个集合属性。如果你创建了一个其元素是RECORD类型的集合,记录的字段只能是标量或者是独享。明确的不可用于集合的数据类型包括BOOLEAN、NCHAR、NCLOB、NVARCHAR2、REF CURSOR、TABLE和VARRAY(非SQL数据类型)。NOT NULL:表明这种类型的变量不能有任何空元素。不过,集合本身可可以是原子级的空(未初始化)。FORCE:这个关键字告诉数据库的是,当要删除这个类型时,就算是其他类型中还有对这个类型的引用,也要强行删除这个类型。比如,如果在一个对象类型的定义中用到了某个特殊的集合类型,你可以使用FORCE关键字来强行删除这个集合类型。

2.3声明VARRAY

和嵌套表类型的声明一样,可以数据库内或者PL/SQL代码块中声明VARRAY类型。

在数据库内创建一个VARRAY类型:

CREATE [OR REPLACE] TYPE type_name AS | IS VARRAY (max_elements) OF element_datatype [ NOT NULL ];

删除数据库内的VARRAY类型:

DROP TYPE type_name [FORCE];

在PL/SQL中声明一个VARRAY类型:

TYPE type_name IS VARRAY (max_elements) OF element_datatype [ NOT NULL ];

其中:

OR REPLACE:允许我们重创建一个已经存在的类型。通过在语法中加上REPLACE的方式来重建类型,而不是先删除后再重新创建,可以把所有已经授予的权限都完整的保留下来。type_name:一个合法的SQL或者PL/SQL标志符。这也是我们以后在声明变量或者列时会用到的标识符。element_datatype:这是集合元素的数据类型。集合内所有元素都是一种类型的,可以是大部分标量数据类型、对象类型、或者REF对象类型。如果集合的元素是对象,对象类型本身不能再带有一个集合属性。如果你创建了一个其元素是RECORD类型的集合,记录的字段只能是标量或者是独享。明确的不可用于集合的数据类型包括BOOLEAN、NCHAR、NCLOB、NVARCHAR2、REF CURSOR、TABLE和VARRAY(非SQL数据类型)。NOT NULL:表明这种类型的变量不能有任何空元素。不过,集合本身可可以是原子级的空(未初始化)。max_elements:VARRAY中元素的最大数量,这个值一旦声明就不能更改。FORCE:这个关键字告诉数据库的是,当要删除这个类型时,就算是其他类型中还有对这个类型的引用,也要强行删除这个类型。比如,如果在一个对象类型的定义中用到了某个特殊的集合类型,你可以使用FORCE关键字来强行删除这个集合类型。

3.集合变量的声明和初始化

3.1集合变量的声明

一旦我们创建好了集合类型,我们就可以根据这个集合类型声明该类型的变量。一个集合变量声明格式如下:

collection_name collection_type [:=collection_type(...)];

其中,collection_name是集合变量的名字,collection_type具有两层含义,它即代表着一个先前已经声明的集合类型的名字,同时也代表着(如果是嵌套表或者VARRAY的话)和该类型同名的构造函数。

构造函数的名字和类型的名字是相同的,并且接收一个用逗号分隔的元素列表作为参数。如果我们声明的是一个嵌套表或者VARRAY变量,我们在使用之前必须要先对这个变量进行初始化。

3.2集合变量的初始化

对于嵌套表类型集合变量和VARRAY类型集合变量,在使用集合变量之前必须要进行初始化,而对于关联数组类型不需要初始化。下面主要讨论嵌套表和VARRY的初始化。

3.2.1通过构造函数的显示初始化

通过构造函数显示地给集合变量初始。例如:

declarevnt_employee nt_employee :=nt_employee(); --不带参数的构造函数初始化vnt_employee nt_employee :=nt_employee('张三','李四','王五'); --带参数的构造函数初始化beginnull;end;

3.2.2直接赋值时的隐式初始化

如果两个集合实例是基于同一集合类型,我们可以把其中一个实例的全部内容拷贝给另一个,这就相当于进行了初始化。例如:

declarevnt_employee nt_employee :=nt_employee('James','Lucy','Jordan');vnt_foregin_employee nt_employee;beginvnt_foregin_employee := vnt_employee;end;

3.2.3通过FETCH操作的隐式初始化

在使用FETCH或者 SELECT INTO语句从数据库提取提取一个集合并保存到一个集合变量时,集合变量会自动初始化,就像直接赋值一样。

declarevnt_colors nt_color;beginselect colors into vnt_colors from color_models; --表color_models的color列是嵌套表类型。end;

3.2.4通过BULK COLLECT语句的隐式初始

使用BULK COLLECT INTO语句批量提取数据并保存到一个集合变量,集合变量会自动初始化,就像直接赋值一样。

declarevnt_employee nt_employee; --未初始化beginselect e.ename bulk collect intovnt_employee from emp e;end;declarecursor cur_employee is select e.ename from emp e;vnt_employee nt_employee; --未初始化beginopen cur_employee;fetch cur_employee bulk collect into vnt_employee;close cur_employee;end;

4.集合方法

Oracle提供了提供许多内置的函数和过程可以用于获取集合的信息或者修改集合的内容,这些方法也叫做集合方法。下面给出这些方法的完整列表:

方法(函数或者过程)

说 明

COUNT函数

返回集合中现有元素的数量

DELETE过程

从集合中移除一个或者多个元素。如果不是重复移除,会减少COUNT的值,对于VARRAY,你只能删除集合的所有元素

EXISTS函数

根据某个指定的元素是否已经在集合中,返回TURE或者FALES

EXTEND过程

增加嵌套表或者VARRAY中元素的个数,同时增加COUNT的值

FIRST、LAST函数

返回可用的最小(FIRST)和最大(LAST)集合下标

LIMIT函数

返回VARRAY中允许ude最大元素数量

PRIOD、NEXT函数

返回紧挨着指定的下标之前(PRIOD)或者之后(NEXT)的下标值。你应该总是用PRIOD和NEXT在集合内遍历,尤其在使用稀疏(或者可能是稀疏)集合时更是如此

TRIM过程

从集合的尾部(定义的最大下标)移除集合元素

之所以把这些过程叫做方法,是因为使用这些集合内置程序的语法不同于调用过程和函数的正规语法。

5.集合类型对比

6.集合示例

6.1关联数组示例

set serverout on --开启sqlplus屏幕打印功能
DECLARETYPE nt_foregn_employee IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;--声明 nt_foregn_employee为关联集合类型 相对于创建一个集合类型--这里由于varchar2(30)类型是数据库自带的,就不需要我们单独创建-- 这里key为binary_integer 类型 value 为varchar2(30)vnt_foregn_employees nt_foregn_employee; --声明 vnt_foregn_employees为 nt_foregn_employee类型v_row                NUMBER;
BEGINvnt_foregn_employees(-230002) := 'SCOTT'; --往 vnt_foregn_employees中添加元素 相当于 map(-230002,'SCOTT');vnt_foregn_employees(-23) := 'JONES';vnt_foregn_employees(1) := 'ALLEN';vnt_foregn_employees(5934) := 'CLARK';vnt_foregn_employees(13342) := 'ADAMS';vnt_foregn_employees(8234223) := 'KING';--使用FIRST方法获取集合中的一个行号v_row := vnt_foregn_employees.first;WHILE (v_row IS NOT NULL) LOOP--遍历集合中的元素dbms_output.put_line(v_row || ':' || vnt_foregn_employees(v_row));v_row := vnt_foregn_employees.next(v_row);END LOOP;
END;
/

在稀疏集合中,经常需要使用NEXT方法遍历集合,提取数据。
查看执行结果,看到遍历结果和我们添加结果一样

在稀疏集合中,经常需要使用NEXT方法遍历集合,提取数据。

6.2嵌套表示例

 DECLARETYPE nt_employee IS TABLE OF emp%ROWTYPE;--声明nt_employee为嵌套表emp集合类型vnt_employees nt_employee := nt_employee(); --构造函数显示初始化c_big_number  NUMBER := power(2, 31);l_start_time  PLS_INTEGER;CURSOR cur_employee IS   --从emp表取数游标SELECT * FROM emp;vrt_employees cur_employee%ROWTYPE;BEGINOPEN cur_employee;LOOPFETCH cur_employeeINTO vrt_employees;EXIT WHEN cur_employee%NOTFOUND;vnt_employees.extend;--嵌套表extend扩展一个元素vnt_employees(vnt_employees.last) := vrt_employees;--添加元素END LOOP;CLOSE cur_employee;--循环遍历元素FOR i IN 1 .. vnt_employees.count LOOP--v_data.count表示集合中元素的个数--vnt_employees 一条记录相当于一个实体,列名相对于是实体属性,通过点的方式获取dbms_output.put_line('empnofrom:' || vnt_employees(i).empno ||' ename:' || vnt_employees(i).ename || ' deptno:' || vnt_employees(i).deptno);--把满足条件的客户信息打印到屏幕END LOOP;dbms_output.put_line('嵌套表vnt_employees中元素个数:'||vnt_employees.count); -- 打印集合的元素总数
END;
/  --sqlplus执行过程命令

执行结果

6.3VARRAY实例

--创建集合类型nt_course 用于存放学生课程表
create or replace type nt_course is varray(5) of varchar2(100);
/
--创建表students,表中引用了可变集合类型nt_course  存放学生和课程信息
create table students( student_name varchar2(20) , cource nt_course);declare
vnt_nt_courses nt_course := nt_course();--构造函数初始化begin
vnt_nt_courses.extend(2);-- 集合增加2个元素
vnt_nt_courses(1) := 'English';--跟一维数组添加元素一样
vnt_nt_courses(2) := 'Chinese';-- 把集合数据添加到students表中
insert into students
(student_name, cource)
values
('chiclewu', vnt_nt_courses);
commit;-- 提交事务
end;
/
select * from table (select s.cource from students s);

– 可以使用TABLE函数把一个集合映射成数据库表.例如,要获取student表中课程列的记录。

这里用table的原因就是集合是不能显示的,

SELECT t.student_name,  t.cource  FROM students t;

看到,通过集合元素可以实现在同一表中一条记录对应多条记录。

我们可以认为其实这里是两个表,
students表中存放学生和选课信息,而选课信息就是我们所说的集合 也相当于是一个表

本文转自:https://www.2cto.com/database/201312/264383.html

oracle集合类型详解相关推荐

  1. redis的数据结构||1) 字符串类型2) 哈希类型3) 列表类型4) 集合类型 5) 有序集合类型详解

    2. 下载安装     1. 官网:https://redis.io     2. 中文网:http://www.redis.net.cn/     3. 解压直接可以使用:         * re ...

  2. Oracle 集合操作详解(并集 union、交集 intersect、差集 minus)

    文章目录 1 概述 2 示例 1 概述 1. Oracle 中有三种集合操作(1) 并集 union all -- 不去重,不排序,效率高union -- 去重,默认排序,效率低 (2) 交集 int ...

  3. Dart学习笔记六:集合类型详解

    目录 前言 List Set Map 集合的遍历 forEach map where any every 前言 Dart的集合类型使用感觉跟ES6中的集合差不多,这里整理一下Dart集合的常用属性和方 ...

  4. Python集合类型详解(一)——集合定义与集合操作符

    今天继续给大家介绍Python相关知识,本文主要内容是Python集合类型定义与集合操作符. 一.集合类型定义 在Python中,集合是一种非常重要的组合数据类型.Python中的集合与数学中的集合非 ...

  5. 2.13 集合类型详解

    集合类型 这里的集合同数学意义上的集合,符合数学集合的特性,具有无序性.确定性和互异性. 集合的特点: 1.集合元素不可更改,不能够是可变的数据类型. 2.集合用大括号来表示,,元素之间用逗号分隔. ...

  6. python序列类型-Python内置序列类型之集合类型详解

    1.集合概念 具有某种特定性质的事物的总体,集合里的东西叫作元素.Python中,集合(set)是一个无序不重复元素的序列. 2.集合的创建 可以使用大括号 { } 或者 set() 函数创建集合,注 ...

  7. 【python 笔记】集合类型详解

    目录 集合: 创建集合 集合的基本操作 集合的内建函数和方法 面向可变集合的内建函数 集合: 无序不重复的元素的组合 利用集合可以删除列表中的重复项(set()唱用作去重操作) 分类:可变集合(set ...

  8. Oracle集合查询详解加练习题

    #集合查询 概念:将不同的数据集合(SQL查询语句)按照集合的规则,拼接一个临时的,新的数据集合(表) 1.集合:并集.交集.差集 并集 union all 语法:select column1,COL ...

  9. 自定义PMD检测的类型集合(详解)

    自定义PMD检测的类型集合 PMD所能检测的类型(八大种) 使用方法 使用xml配置文件配置多条规则 1.在resources目录下写个配置文件 settings.xml(命名无要求) 2.confi ...

最新文章

  1. 解决微信H5获取SDK授权报错提示errMsg: “config:fail,Error: 系统错误,错误码:63002,invalid signature [20200908 22:17:17][]“
  2. 2018最后一个月的Python热文Top10!赶紧学起来~
  3. sql定位过程报错_如何得到plsql中执行时报错的SQL的位置行号
  4. oracle数据库备份方法主要有哪几种,Oracle数据库备份方法有哪三种?
  5. 想拥有一台属于你自己的无人机嘛?
  6. 无旋treap的简单思想以及模板
  7. html整体引入js,html页面用js引入js的方式
  8. gitlab mr wip 怎么弄成_基于GitLab的工作流程设计
  9. 如何避免JDBC内存溢出问题
  10. 程序员新年要实现的10个愿望
  11. linux十分钟调度一次,linux系统任务调度命令crontab
  12. 问题十七:怎么用ray tracing画多个球?
  13. Echarts直方图
  14. mcu AD采样值和物理值
  15. 【深度学习】关于pytorch中使用pretrained的模型,对模型进行调整
  16. 前端工程师就业班Sass基础+进阶+案例开发经验【JS++前端】-艾小野-专题视频课程...
  17. ux pm_如何从学术研究人员过渡到UX研究人员
  18. 小程序开发系列之基础部分-账号注册
  19. 关于日志造成的频繁的IO
  20. 【Kotlin】Kotlin 函数总结 ( 具名函数 | 匿名函数 | Lambda 表达式 | 闭包 | 内联函数 | 函数引用 )

热门文章

  1. 震惊!这篇文章解读数据仓库、数据湖、数据中台等概念,竟然写了4万字!
  2. 一周信创舆情观察(7.13~7.19)
  3. Thinkphp 6 + Vue 2 + ElementUI + Vxe-table 前后端分离的,一键生成代码和API接口的,通用后台管理系统 快速开发框架,开发小程序和APP的推荐框架!
  4. 第五人格服务器维修到几点,第五人格1月10日更新几点结束 第五人格1月10日更新维护公告...
  5. swift篇 基础知识5 -- 字符串(String)和字符(character)
  6. 如何ping通带端口的网址
  7. [前端踩坑]引入组件报错Already included file name ‘XXX‘ differs from file name ‘XXX‘ only in casing.
  8. 游戏引擎开发中常用的设计模式
  9. 你肯定没用过这个全新的 Git 客户端工具!
  10. 10款js图片代码_图片滚动代码_图片切换代码_图片特效代码_图片轮播代码(一)