DM 支持使用 CREATE TYPE 语句创建自定义类型,具体为记录类型、对象类型、数组类型和集合类型。
记录类型
在DM数据库中,可以使用CREATE TYPE
语句创建记录类型。记录类型由多个字段组成,适用于将逻辑相关的数据组合为一个整体。以下是创建记录类型的示例和说明:
举例1. 创建记录类型-没有赋值
使用CREATE TYPE
语句定义记录类型,指定字段名和数据类型:
CREATE OR REPLACE TYPE PersonRec AS RECORD (
id INT,
name VARCHAR(50),
age INT
);
- 在DMSQL程序中使用记录类型
声明记录变量并操作字段:
DECLARE
v_person PersonRec;
BEGIN
-- 赋值
v_person.id := 1;
v_person.name := '张三';
v_person.age := 30;
-- 使用字段值(例如插入表或输出)
PRINT 'ID: ' || v_person.id || ', 姓名: ' || v_person.name || ', 年龄: ' || v_person.age;
END;
- 从查询结果填充记录
可将查询结果直接存入记录变量:
DECLARE
v_emp PersonRec;
BEGIN
SELECT employeeid, employeename, age INTO vemp.id, vemp.name, v_emp.age
FROM employees
WHERE employee_id = 1001;
PRINT '员工姓名: ' || v_emp.name;
END;
关键说明
字段类型支持:记录字段可以是基础类型(如INT
、VARCHAR
)或其他自定义类型(如嵌套记录、数组)。
使用限制:记录类型不能直接作为表的列类型,仅适用于DMSQL程序中的变量、参数或返回值。
动态赋值:支持通过.
操作符单独访问字段,或整体赋值给另一兼容记录。
应用场景
数据聚合:将多个关联字段作为整体传递。
简化逻辑:在存储过程或函数中处理复杂数据结构。
通过CREATE TYPE
定义的记录类型,增强了代码的结构化和可维护性,适用于需要封装多个数据字段的场景。
举例2 创建一个包含默认值的记录类型
CREATE TYPE employee_info AS RECORD (
EMP_ID INT DEFAULT 0,
EMP_NAME VARCHAR2(50) := '未命名',
DEPT_ID INT
);
/
声明并使用变量:
DECLARE
v_emp employee_info;
BEGIN
-- 直接赋值不指定默认值
v_emp.EMP_ID := 101;
v_emp.EMP_NAME := '张三';
-- 查询并使用记录类型变量
PRINT 'EMP_ID = ' || v_emp.EMP_ID;
PRINT 'EMP_NAME = ' || v_emp.EMP_NAME;
PRINT 'DEPT_ID = ' || v_emp.DEPT_ID;
END;
/
对象类型
完整示例总结
完整的对象类型创建和使用流程如下:
- 创建对象类型 COMPLEX(定义属性和方法)。
- 创建类型体 COMPLEX(实现方法)。
- 创建表 C_TAB 并使用 COMPLEX 类型作为列类型。
- 插入数据并调用对象方法进行计算。
- 在存储过程中使用 COMPLEX 类型作为参数。
示例 1:创建简单的对象类型
以下示例创建一个名为 COMPLEX 的对象类型,包含两个属性 RPART 和 IPART,以及两个方法 PLUS 和 LES:
– 创建对象类型
CREATE TYPE COMPLEX AS OBJECT
(
RPART INT,-- 实部
IPART INT,-- 虚部
-- 方法声明
FUNCTION PLUS(X COMPLEX) RETURN COMPLEX,
FUNCTION LES(X COMPLEX) RETURN COMPLEX
);
/
COMPLEX 对象类型包含两个整数属性 RPART 和 IPART。
FUNCTION PLUS 和 LES 是两个方法,分别用于实现复数的加法和减法。
示例 2:创建类型体
对象类型的常用方法需要通过 CREATE TYPE BODY 语句进行定义。以下是上述 COMPLEX 对象类型的类型体定义:
-- 创建类型体
CREATE TYPE BODY COMPLEX AS
(
FUNCTION PLUS(X COMPLEX) RETURN COMPLEX IS
BEGIN
RETURN COMPLEX(RPART + X.RPART, IPART + X.IPART);
END;
FUNCTION LES(X COMPLEX) RETURN COMPLEX IS
BEGIN
RETURN COMPLEX(RPART - X.RPART, IPART - X.IPART);
END;
);
/
PLUS 方法实现复数的加法。
LES 方法实现复数的减法。
3. 使用自定义对象类型
示例:在表中使用对象类型
以下示例展示如何将自定义对象类型 COMPLEX 作为表列的类型,并进行数据操作:
– 创建表,使用对象类型作为列类型
CREATE TABLE C_TAB
(
C1 INT,
C2 COMPLEX
);
– 插入数据
INSERT INTO C_TAB VALUES(1, COMPLEX(2, 3));
– 调用对象方法进行计算
INSERT INTO C_TAB
SELECT 2, COMPLEX(4, 2).PLUS(COMPLEX(2, 3)) FROM DUAL;
– 查询数据
SELECT C2.RPART, C2.IPART FROM C_TAB;
– 示例输出:
-- C2.RPART | C2.IPART
-- 2 | 3
-- 6 | 5
示例:在程序中使用对象类型
以下示例展示如何在存储过程中使用自定义对象类型 COMPLEX:
– 创建存储过程,使用对象类型作为参数
CREATE OR REPLACE PROCEDURE proc_complex(a COMPLEX DEFAULT COMPLEX(2, 3))
AS
b COMPLEX;
BEGIN
a.RPART := a.RPART + 100;
b := a;
PRINT b.RPART;
END;
/
调用存储过程:
CALL proc_complex();
– 输出结果:
– 102
数组类型
DM 支持使用 CREATE TYPE 语句创建数组类型,包括静态数组和动态数组。以下是具体的示例说明:
1. 静态数组类型的创建
静态数组类型是在声明时就指定了数组的长度,其大小在程序运行期间不能改变。
语法格式:
CREATE TYPE <数组名> AS ARRAY <数据类型> [' [<常量表达式>]{,<常量表达式>}'];
示例 1:创建一个一维静态整数数组
CREATE TYPE IntArray AS ARRAY INT[5];
/
示例 2:创建一个二维静态 VARCHAR 数组
CREATE TYPE VarCharArray AS ARRAY VARCHAR[3,4];
/
2. 动态数组类型的创建
动态数组类型的大小可以在程序运行期间动态调整。
语法格式:
CREATE TYPE <数组名> AS ARRAY <数据类型> [{,}];
示例 1:创建一个一维动态整数数组
CREATE TYPE DynamicIntArray AS ARRAY INT[];
/
示例 2:创建一个二维动态 VARCHAR 数组
CREATE TYPE DynamicVarCharArray AS ARRAY VARCHAR[,];
/
3. 数组类型的使用
以下是一个完整的示例,展示如何使用 CREATE TYPE 创建数组类型,并在程序中使用它。
举例1
步骤 1:创建一维动态整数数组类型
CREATE TYPE DynamicIntArray AS ARRAY INT[];
/
步骤 2:使用动态数组类型声明变量并在程序中动态分配空间
DECLARE
TYPE IntArrayVar IS ARRAY INT[];
a IntArrayVar;
BEGIN
a := NEW INT[5]; -- 动态分配空间,创建一个长度为 5 的整数数组
FOR I IN 1..5 LOOP
a[I] := I * 10;
PRINT a[I];
END LOOP;
END;
/
输出结果:
10
20
30
40
50
- 复杂类型数组
静态数组和动态数组中的 <数据类型> 除了支持普通数据类型(如 INT、VARCHAR 等),还支持复杂数据类型(如记录类型、嵌套数组等)。
示例:创建一个嵌套数组类型(如二维整数数组)
CREATE TYPE NestedIntArray AS ARRAY INT[5];
/
CREATE TYPE TwoDimensionalIntArray AS ARRAY NestedIntArray[3];
/
使用嵌套数组类型的示例程序:
DECLARE
TYPE TwoDimensionalIntVar IS ARRAY NestedIntArray[3];
arr TwoDimensionalIntVar;
BEGIN
arr := NEW NestedIntArray[3];
FOR I IN 1..3 LOOP
arr[I] := NEW INT[5];
FOR J IN 1..5 LOOP
arr[I][J] := I * 10 + J;
END LOOP;
END LOOP;
-- 打印二维数组的内容
FOR I IN 1..3 LOOP
FOR J IN 1..5 LOOP
PRINT 'arr[' || I || '][' || J || '] = ' || arr[I][J];
END LOOP;
END LOOP;
END;
/
举例2
- 创建示例
示例1:静态整型数组
-- 创建静态数组类型(长度5)
CREATE OR REPLACE TYPE intstaticarray AS ARRAY INTEGER[5];
示例2:动态字符串数组(VARRAY)
-- 创建动态数组类型(最大容量100)
CREATE OR REPLACE TYPE str_varray AS VARRAY(100) OF VARCHAR(50);
- 在表中使用数组类型
步骤1:创建表
CREATE TABLE employee (
id INT,
name VARCHAR(30),
projects str_varray -- 使用自定义动态数组类型
);
步骤2:插入数据
INSERT INTO employee VALUES
(1, '张三', str_varray('项目A', '项目B')),
(2, '李四', str_varray('项目X', '项目Y', '项目Z'));
步骤3:查询数据
-- 查询所有数据
SELECT * FROM employee;

-- 展开数组元素查询
SELECT id, name, t.*
FROM employee, TABLE(employee.projects) t;
- 关键注意事项
索引从1开始:达梦数组元素下标起始为1(非0)。
长度限制:静态数组每维最大长度65534,动态数组受内存限制。
复杂类型支持:数组元素可为记录、对象或其他集合类型。
- 扩展操作
修改数组元素:
UPDATE employee
SET projects = str_varray('新项目A', '新项目B')
WHERE id = 1;
动态扩展:VARRAY在插入时自动扩展,但不可超过声明的最大容量。
5. 注意事项
数组的下标从 1 开始,不支持 0 开始。
静态数组的长度在创建时指定,无法动态调整;动态数组的长度可以在运行时动态分配。
复杂类型数组(如嵌套数组、记录类型数组等)的使用需要先定义嵌套类型,再创建数组类型。
长度限制:静态数组每维最大长度65534,动态数组受内存限制。
复杂类型支持:数组元素可为记录、对象或其他集合类型。
集合类型
达梦数据库支持使用 CREATE TYPE
语句创建集合类型,包括以下三种形式:
- 数组集合(VARRAY)
定义:元素个数有限且有序的集合,需指定最大容量。
语法示例:
CREATE OR REPLACE TYPE ARR_NUM AS VARRAY(3) OF NUMBER;
应用举例:
-- 创建表,使用数组集合类型作为列类型
CREATE TABLE T1 (C1 INT, C2 ARR_NUM);
-- 插入数据(需调用构造函数初始化)
INSERT INTO T1 VALUES (1, ARR_NUM(1, 2));
INSERT INTO T1 VALUES (2, ARR_NUM(3, 4, 5));
-- 查询展开数组内容
SELECT * FROM TABLE(SELECT C2 FROM T1 WHERE C1=2);
输出:
COLUMN_VALUE
3
4
5
- 嵌套表(TABLE OF)
定义:元素个数无限制的表结构,可动态扩展。
语法示例:
CREATE OR REPLACE TYPE T_CHA AS TABLE OF CHAR;
应用举例:
-- 创建表,使用嵌套表类型作为列类型
CREATE TABLE T2 (C1 INT, C2 T_CHA);
-- 插入数据
INSERT INTO T2 VALUES (1, T_CHA('A', 'B'));
INSERT INTO T2 VALUES (2, T_CHA('C', 'D', 'E'));
-- 查询展开嵌套表内容
SELECT * FROM TABLE(SELECT C2 FROM T2 WHERE C1=1);
输出:
COLUMN_VALUE
A
B
- 索引表(TABLE OF INDEX BY)
定义:通过键值(整数或字符串)访问的关联数组。
语法示例(以字符串为键):
-- 定义索引表类型(需在DMSQL程序块中声明)
DECLARE
TYPE IDX_TAB IS TABLE OF VARCHAR(20) INDEX BY VARCHAR(100);
vtab IDXTAB;
BEGIN
v_tab('key1') := 'Value1';
v_tab('key2') := 'Value2';
PRINT v_tab('key1');
END;
输出:
Value1
关键点总结
元素类型:支持基础类型(如NUMBER
、CHAR
)或自定义类型(如对象、记录)。
约束:可添加 NOT NULL
限制元素非空。
使用场景:集合类型可直接作为表的列类型,或用于DMSQL程序中的变量及参数。
查询扩展:通过 TABLE()
函数展开集合内容进行查询。