结构化查询语言 DM_SQL 简介

结构化查询语言 SQL (Structured Query Language) 是在 1974 年提出的一种关系数据库语言。由于 SQL 语言接近英语的语句结构,方便简洁、使用灵活、功能强大,倍受用户及计算机工业界的欢迎,被众多计算机公司和数据库厂商所采用,经各公司的不断修改、扩充和完善,SQL 语言最终发展成为关系数据库的标准语言。

SQL 的第一个标准是 1986 年 10 月由美国国家标准化组织 (ANSI) 公布的 ANSIX3.135-1986 数据库语言 SQL,简称 SQL-86,1987 年国际标准化组织 (ISO) 也通过了这一标准。以后通过对 SQL-86 的不断修改和完善,于 1989 年第二次公布了 SQL 标准 ISO/IEC 9075-1989(E),即SQL-89。1992年又公布了SQL标准ISO/IEC 9075:1992,即 SQL-92。1999 年公布了 ISO/IEC 9075:1999,即 SQL-3 (也称 SQL-99)。之后在 2003 年公布了 ISO/IEC 9075:2003,即 SQL:2003;在 2008 年公布了 ISO/IEC 9075:2008,即 SQL:2008;在2011年公布了 ISO/IEC 9075:2011,即 SQL:2011。由于 SQL 标准的内容越来越庞杂,绝大多数情况下,说起 SQL 符合程度,其实是指 SQL-92 中最核心的部分,从 SQL-99 后不再对标准符合程度进行分级,而是改成了核心兼容性和特性兼容性。

SQL成为国际标准以后,其影响远远超出了数据库领域。例如在 CAD、软件工程、人工智能、分布式等领域,人们不仅把 SQL 作为检索数据的语言规范,而且也把 SQL 作为检索图形、图象、声音、文字等信息类型的语言规范。目前,世界上大型的著名数据库管理系统均支持 SQL 语言,如 Oracle、Sybase、SQL Server、DB2 等。在未来相当长的时间里,SQL 仍将是数据库领域以至信息领域中数据处理的主流语言之一。

由于不同的 DBMS 产品,大都按自己产品的特点对 SQL 语言进行了扩充,很难完全符合SQL标准。目前在 DBMS 市场上已将 SQL 的符合率作为衡量产品质量的重要指标,并研制成专门的测试软件,如 NIST。目前,DM 数据库管理系统 SQL-92 入门级符合率达到 100%,过渡级符合率达到 95%,并且部分支持 SQL-99、SQL:2003、SQL:2008 和 SQL:2011 的特性。同时 DM 还兼容 Oracle 11g 和 SQL Server 2008 的部分语言特性。本章主要介绍 DM 系统所支持的 SQL 语言—— DM_SQL 语言。

1.1 DM_SQL 语言的特点

DM_SQL 语言符合结构化查询语言 SQL 标准,是标准 SQL 的扩充。它集数据定义、数据查询、数据操纵和数据控制于一体,是一种统一的、综合的关系数据库语言。它功能强大,使用简单方便、容易为用户掌握。DM_SQL 语言具有如下特点:

1.功能一体化

DM_SQL 的功能一体化表现在以下两个方面:

  1. DM_SQL 支持多媒体数据类型,用户在建表时可直接使用。DM系统在处理常规数据与多媒体数据时达到了四个一体化:一体化定义、一体化存储、一体化检索、一体化处理,最大限度地提高了数据库管理系统处理多媒体的能力和速度;
  2. DM_SQL语言集数据库的定义、查询、更新、控制、维护、恢复、安全等一系列操作于一体,每一项操作都只需一种操作符表示,格式规范,风格一致,简单方便,很容易为用户所掌握。

2.两种用户接口使用统一语法结构的语言

DM_SQL语言既是自含式语言,又是嵌入式语言。作为自含式语言,它能独立运行于联机交互方式。作为嵌入式语言,DM_SQL语句能够嵌入到C和C++语言程序中,将高级语言(也称主语言)灵活的表达能力、强大的计算功能与DM_SQL语言的数据处理功能相结合,完成各种复杂的事务处理。而在这两种不同的使用方式中,DM_SQL语言的语法结构是一致的,从而为用户使用提供了极大的方便性和灵活性。

3.高度非过程化

DM_SQL语言是一种非过程化语言。用户只需指出“做什么”,而不需指出“怎么做”,对数据存取路径的选择以及 DM_SQL 语句功能的实现均由系统自动完成,与用户编制的应用程序与具体的机器及关系DBMS的实现细节无关,从而方便了用户,提高了应用程序的开发效率,也增强了数据独立性和应用系统的可移植性。

4.面向集合的操作方式

DM_SQL 语言采用了集合操作方式。不仅查询结果可以是元组的集合,而且一次插入、删除、修改操作的对象也可以是元组的集合,相对于面向记录的数据库语言 (一次只能操作一条记录) 来说,DM_SQL 语言的使用简化了用户的处理,提高了应用程序的运行效率。

5.语言简洁,方便易学

DM_SQL 语言功能强大,格式规范,表达简洁,接近英语的语法结构,容易为用户所掌握。

1.2 保留字与标识符

标识符的语法规则兼容标准GJB 1382A-9X,标识符分为正规标识符和定界标识符两大类。

正规标识符以字母、_、$、#或汉字开头,后面可以跟随字母、数字、_、$、#或者汉字,正规标识符的最大长度是128个英文字符或64个汉字。正规标识符不能是保留字。

正规标识符的例子:A,test1,_TABLE_B,表1。

定界标识符的标识符体用双引号括起来时,标识符体可以包含任意字符,特别地,其中使用连续两个双引号转义为一个双引号。

定界标识符的例子:"table","A","!@#$"。

保留字的清单参见附录 1。

1.3 DM_SQL 语言的功能及语句

DM_SQL语言是一种介于关系代数与关系演算之间的语言,其功能主要包括数据定义、查询、操纵和控制四个方面,通过各种不同的 SQL 语句来实现。按照所实现的功能,DM_SQL 语句分为以下几种:

  1. 用户、模式、基表、视图、索引、序列、全文索引、存储过程、触发器等数据库对象的定义和删除语句,数据库、用户、基表、视图、索引、全文索引等数据库对象的修改语句;
  2. 查询(含全文检索)、插入、删除、修改语句;
  3. 数据库安全语句。包括创建角色语句、删除角色语句,授权语句、回收权限语句,修改登录口令语句,审计设置语句、取消审计设置语句等。

在嵌入方式中,为了协调 DM_SQL 语言与主语言不同的数据处理方式,DM_SQL 语言引入了游标的概念。因此在嵌入方式下,除了数据查询语句 (一次查询一条记录) 外,还有几种与游标有关的语句:

  1. 游标的定义、打开、关闭、拨动语句;
  2. 游标定位方式的数据修改与删除语句。

为了有效维护数据库的完整性和一致性,支持 DBMS 的并发控制机制,DM_SQL 语言提供了事务的回滚 (ROLLBACK) 与提交 (COMMIT) 语句。同时 DM 允许选择实施事务级读一致性,它保证同一事务内的可重复读,为此DM提供用户多种手动上锁语句,和设置事务隔离级别语句。

1.4 DM_SQL 所支持的数据类型

数据类型是可表示值的集。值的逻辑表示是<字值>。值的物理表示依赖于实现。DM 系统具有 SQL-92 的绝大部分数据类型,以及部分 SQL-99 和 SQL Server 2000 的数据类型。

1.4.1 常规数据类型

1. 字符数据类型

CHAR类型

语法:CHAR[(长度)]

功能:CHAR数据类型指定定长字符串。在基表中,定义CHAR类型的列时,可以指定一个不超过32767的正整数作为字节长度,例如:CHAR(100)。如果未指定长度,缺省为1。CHAR类型列的最大存储长度由数据库页面大小决定,CHAR数据类型最大存储长度和页面大小的对应关系请见下表1.4.1。但是,在表达式计算中,该类型的长度上限不受页面大小限制,为32767。

表1.4.1
数据库页面大小 实际最大长度
4 K 1900
8 K 3900
16 K 8000
32 K 8188

这个限制长度只针对基表中的列,在定义变量的时候,可以不受这个限制长度的限制。另外,实际插入表中的列长度要受到记录长度的约束,每条记录总长度不能大于页面大小的一半。

CHARACTER 类型

语法:CHARACTER[(长度)]

功能:与 CHAR 相同。

VARCHAR 类型/VARCHAR2 类型

语法:VARCHAR[(长度)]

功能:VARCHAR数据类型指定变长字符串,用法类似CHAR数据类型,可以指定一个不超过32767的正整数作为字节或字符长度,例如:VARCHAR (100)指定100字节长度;VARCHAR(100 CHAR)指定100字符长度。如果未指定长度,缺省为8188字节。

在基表中,当没有指定 USING LONG ROW 存储选项时,插入 VARCHAR 数据类型的实际最大存储长度由数据库页面大小决定,具体最大长度算法如表 1.4.1;如果指定了 USING LONG ROW 存储选项,则插入 VARCHAR 数据类型的长度不受数据库页面大小限制。VARCHAR 类型在表达式计算中的长度上限不受页面大小限制,为 32767;

CHAR 同 VARCHAR 的区别在于前者长度不足时,系统自动填充空格,而后者只占用实际的字节空间。另外,实际插入表中的列长度要受到记录长度的约束,每条记录总长度不能大于页面大小的一半。

VARCHAR2 类型和 VARCHAR 类型用法相同。

2. 数值数据类型

  1. 精确数值数据类型

NUMERIC 类型

语法:NUMERIC[(精度 [, 标度])]

功能:NUMERIC 数据类型用于存储零、正负定点数。其中:精度是一个无符号整数,定义了总的数字数,精度范围是 1 至 38。标度定义了小数点右边的数字位数。一个数的标度不应大于其精度,如果实际标度大于指定标度,那么超出标度的位数将会四舍五入省去。例如:NUMERIC(4,1)定义了小数点前面 3 位和小数点后面 1 位,共 4 位的数字,范围在-999.9 到 999.9。所有 NUMERIC 数据类型,如果其值超过精度,DM 会返回一个出错信息,如果超过标度,则多余的位会被截断。

如果不指定精度和标度,缺省精度为 38,标度无限定。

DECIMAL 类型

语法:DECIMAL[(精度 [, 标度])]

功能:与 NUMERIC 相似。

DEC 类型

语法:DEC[(精度[, 标度])]

功能:与 DECIMAL 相同。

NUMBER 类型

语法:NUMBER[(精度[, 标度])]

功能:与 NUMERIC 相同。

INTEGER 类型

语法:INTEGER

功能:用于存储有符号整数,精度为 10,标度为 0。取值范围为:-2147483648 (-231)~ +2147483647(231-1)。

INT 类型

语法:INT

功能:与 INTEGER 相同。

BIGINT 类型

语法:BIGINT

功能:用于存储有符号整数,精度为 19,标度为 0。取值范围为:-9223372036854775808(-263)~9223372036854775807(263-1)。

TINYINT 类型

语法:TINYINT

功能:用于存储有符号整数,精度为 3,标度为 0。取值范围为:-128 ~ +127。

BYTE 类型

语法:BYTE

功能:与 TINYINT 相似,精度为3,标度为0。

SMALLINT 类型

语法:SMALLINT

功能:用于存储有符号整数,精度为 5,标度为 0。取值范围为:-32768(-215) ~ +32767(215-1)。

BINARY 类型

语法:BINARY[(长度)]

功能:BINARY数据类型用来存储定长二进制数据。在基表中,定义BINARY类型的列时,其最大存储长度由数据库页面大小决定,可以指定一个不超过其最大存储长度的正整数作为列长度,缺省长度为1个字节。最大存储长度见表1.4.1。BINARY类型在表达式计算中的长度上限为32767。BINARY常量以0x开始,后面跟着数据的十六进制表示,例如0x2A3B4058。

VARBINARY 类型

语法:VARBINARY[(长度)]

功能:VARBINARY数据类型用来存储变长二进制数据,用法类似BINARY数据类型,可以指定一个不超过32767的正整数作为数据长度。缺省长度为8188个字节。VARBINARY数据类型的实际最大存储长度由数据库页面大小决定,具体最大长度算法与VARCHAR类型的相同,其在表达式计算中的长度上限也与VARCHAR类型相同,为32767。

  1. 近似数值数据类型

FLOAT 类型

语法:FLOAT[(精度)]

功能:FLOAT 是带二进制精度的浮点数。该类型直接使用标准 C 语言中 DOUBLE。精度值设置无实际意义,精度设置用于保证数据移植的兼容性,实际精度在达梦内部是固定的。精度处于范围(1~126)时忽略精度,超过此范围直接报错。

FLOAT取值范围-1.7*10308 ~ 1.7*10308。

DOUBLE 类型

语法:DOUBLE[(精度)]

功能:DOUBLE 是带二进制精度的浮点数。DOUBLE 类型的设置是为了移植的兼容性。该类型直接使用标准 C 语言中 DOUBLE。精度与取值范围用法与 FLOAT 完全一样。

REAL 类型

语法:REAL

功能:REAL 是带二进制精度的浮点数,但它不能由用户指定使用的精度,系统指定其二进制精度为 24,十进制精度为 7。取值范围-3.4*1038 ~ 3.4*1038。

DOUBLE PRECISION 类型

语法:DOUBLE PRECISION[(精度)]

功能:该类型指明双精度浮点数。DOUBLE PRECISION 类型的设置是为了移植的兼容性。该类型直接使用标准 C 语言中 DOUBLE。精度与取值范围用法与 FLOAT 完全一样。

1.4.2 位串数据类型

BIT 类型

语法:BIT

功能:BIT 类型用于存储整数数据 1、0 或 NULL,只有 0 才转换为假,其他非空、非 0 值都会自动转换为真,可以用来支持 ODBC 和 JDBC 的布尔数据类型。DM 的 BIT 类型与 SQL SERVER2000 的 BIT 数据类型相似。

功能与 ODBC 和 JDBC 的 bool 相同。

1.4.3 日期时间数据类型

日期时间数据类型分为一般日期时间数据类型、时间间隔数据类型和时区数据类型三类,用于存储日期、时间和它们之间的间隔信息。

  1. 一般日期时间数据类型

DATE 类型

语法:DATE

功能:DATE 类型包括年、月、日信息,定义了'-4712-01-01'和'9999-12-31'之间任何一个有效的格里高利日期。DM 支持儒略历,并考虑了历史上从儒略历转换至格里高利日期时的异常,不计算'1582-10-05'到'1582-10-14'之间的 10 天。

DM 支持 SQL92 标准或 SQL SERVER 的 DATE 字值,例如:DATE'1999-10-01'、'1999/10/01'或'1999.10.01'都是有效的 DATE 值,且彼此等价。年月日中第一个非 0 数值前的 0 亦可省略,例如'0001-01-01'等价于'1-1-1'。

TIME 类型

语法:TIME[(小数秒精度)]

功能:TIME 类型包括时、分、秒信息,定义了一个在'00:00:00.000000'和'23:59:59.999999'之间的有效时间。TIME 类型的小数秒精度规定了秒字段中小数点后面的位数,取值范围为 0~6,如果未定义,缺省精度为0。

DM 支持 SQL92 标准或 SQL SERVER 的 TIME 字值,例如:TIME '09:10:21','09:10:21'或'9:10:21'都是有效的 TIME 值,且彼此等价。

TIMESTAMP 类型

语法:TIMESTAMP[(小数秒精度)]

功能:TIMESTAMP 类型包括年、月、日、时、分、秒信息,定义了一个在'-4712-01-01 00:00:00.000000'和'9999-12-31 23:59:59.999999'之间的有效格里高利日期时间。TIMESTAMP 类型的小数秒精度规定了秒字段中小数点后面的位数,取值范围为 0~6,如果未定义,缺省精度为 6。与 DATE 类型相同,DM 不计算'1582-10-05'到'1582-10-14'之间的 10 天。

DM 支持 SQL92 标准或 SQL SERVER 的 TIMESTAMP 字值,例如:TIMESTAMP '2002-12-12 09:10:21'或'2002-12-12 9:10:21'或'2002/12/12 09:10:21'或'2002.12.12 09:10:21'都是有效的 TIMESTAMP 值,且彼此等价。

语法中,TIMESTAMP 也可以写为 DATETIME。

  1. 时间间隔数据类型

DM支持两类十三种时间间隔类型:两类是年-月间隔类和日-时间隔类,它们通过时间间隔限定符区分,前者结合了日期字段年和月,后者结合了时间字段日、时、分、秒。由时间间隔数据类型所描述的值总是有符号的。

需要说明的是,使用时间间隔数据类型时,如果使用了其引导精度的默认精度,要注意保持精度匹配,否则会出现错误。如果不指定精度,那么将使用默认精度 6。

  1. 年-月间隔类

INTERVAL YEAR TO MONTH 类型

语法:INTERVAL YEAR[(引导精度)]TO MONTH

功能:描述一个若干年若干月的间隔,引导精度规定了年的取值范围。引导精度取值范围为 1~9,如果未定义,缺省精度为2。月的取值范围在 0 到 11 之间。例如:INTERVAL YEAR(4) TO MONTH,其中 YEAR(4) 表示年的精度为 4,表示范围为负 9999 年零 12 月到正 9999 年零 12 月。一个合适的字值例子是:INTERVAL '0015-08' YEAR TO MONTH。

INTERVAL YEAR 类型

语法:INTERVAL YEAR[(引导精度)]

功能:描述一个若干年的间隔,引导精度规定了年的取值范围。引导精度取值范围为 1~9,如果未定义,缺省精度为 2。例如:INTERVAL YEAR(4),其中 YEAR(4) 表示年的精度为 4,表示范围为负 9999 年到正 9999 年。一个合适的字值例子是:INTERVAL '0015' YEAR。

INTERVAL MONTH 类型

语法:INTERVAL MONTH[(引导精度)]

功能:描述一个若干月的间隔,引导精度规定了月的取值范围。引导精度取值范围为 1~9,如果未定义,缺省精度为 2。例如:INTERVAL MONTH(4),其中MONTH(4)表示月的精度为 4,表示范围为负 9999 月到正 9999 月。一个合适的字值例子是:INTERVAL '0015' MONTH。

  1. 日-时间隔类

INTERVAL DAY 类型

语法:INTERVAL DAY[(引导精度)]

功能:描述一个若干日的间隔,引导精度规定了日的取值范围。引导精度取值范围为 1~9,如果未定义,缺省精度为 2。例如:INTERVAL DAY(3),其中 DAY (3) 表示日的精度为 3,表示范围为负 999 日到正 999 日。一个合适的字值例子是:INTERVAL '150' DAY。

INTERVAL DAY TO HOUR 类型

语法:INTERVAL DAY[(引导精度)] TO HOUR

功能:描述一个若干日若干小时的间隔,引导精度规定了日的取值范围。引导精度取值范围为 1~9,如果未定义,缺省精度为 2。而时的取值范围在 0 到 23 之间。例如:INTERVAL DAY(1) TO HOUR,其中 DAY(1) 表示日的精度为 1,表示范围为负 9 日零 23 小时到正9日零23小时。一个合适的字值例子是:INTERVAL '9 23' DAY TO HOUR。

INTERVAL DAY TO MINUTE 类型

语法:INTERVAL DAY[(引导精度)] TO MINUTE

功能:描述一个若干日若干小时若干分钟的间隔,引导精度规定了日的取值范围。引导精度取值范围为1~9,如果未定义,缺省精度为2。而小时的取值范围在0到23之间,分钟的取值范围在0到59之间。例如:INTERVAL DAY(2) TO MINUTE,其中DAY(2)表示日的精度为2,表示范围为负99日零23小时零59分到正99日零23小时零59分。一个合适的字值例子是:INTERVAL '09 23:12' DAY TO MINUTE。

INTERVAL DAY TO SECOND类型

语法:INTERVAL DAY[(引导精度)] TO SECOND [(小数秒精度)]

功能:描述一个若干日若干小时若干分钟若干秒的间隔,引导精度规定了日的取值范围。引导精度取值范围为1~9,如果未定义,缺省精度为2。小数秒精度规定了秒字段中小数点后面的位数,取值范围为0~6,如果不定义小数秒精度默认精度为6。小时的取值范围在0到23之间,分钟的取值范围在0到59之间。例如:INTERVAL DAY(2) TO SECOND(1),其中DAY(2)表示日的精度为2,SECOND(1)表示秒的小数点后面取1位,表示范围为负99日零23小时零59分零59.9秒到正99日零23小时零59分零59.9秒。一个合适的字值例子是:INTERVAL '09 23:12:01.1' DAY TO SECOND。

INTERVAL HOUR类型

语法:INTERVAL HOUR[(引导精度)]

功能:描述一个若干小时的间隔,引导精度规定了小时的取值范围。引导精度取值范围为1~9,如果未定义,缺省精度为2。例如:INTERVAL HOUR(3),其中HOUR (3)表示时的精度为3,表示范围为负999小时到正999小时。一个合适的字值例子是:INTERVAL '150' HOUR。

INTERVAL HOUR TO MINUTE类型

语法:INTERVAL HOUR[(引导精度)] TO MINUTE

功能:描述一个若干小时若干分钟的间隔,引导精度规定了小时的取值范围。引导精度取值范围为1~9,如果未定义,缺省精度为2。而分钟的取值范围在0到59之间。例如:INTERVAL HOUR(2) TO MINUTE,其中HOUR(2)表示小时的精度为2,表示范围为负99小时零59分到正99小时零59分。一个合适的字值例子是:INTERVAL '23:12' HOUR TO MINUTE。

INTERVAL HOUR TO SECOND类型

语法:INTERVAL HOUR[(引导精度)] TO SECOND [(小数秒精度)]

功能:描述一个若干小时若干分钟若干秒的间隔,引导精度规定了小时的取值范围。引导精度取值范围为1~9,如果未定义,缺省精度为2。小数秒精度规定了秒字段中小数点后面的位数,取值范围为0~6,如果未定义,缺省精度为6。分钟的取值范围在0到59之间。例如:INTERVAL HOUR(2) TO SECOND(1),其中HOUR(2)表示小时的精度为2,SECOND(1)表示秒的小数点后面取1位,表示范围为负99小时零59分零59.9秒到正99小时零59分零59.9秒。一个合适的字值例子是:INTERVAL '23:12:01.1' HOUR TO SECOND。

INTERVAL MINUTE类型

语法:INTERVAL MINUTE[(引导精度)]

功能:描述一个若干分钟的间隔,引导精度规定了分钟的取值范围。引导精度取值范围为1~9,如果未定义,缺省精度为2。例如:INTERVAL MINUTE(3),其中MINUTE(3)表示分钟的精度为3,表示范围为负999分钟到正999分钟。一个合适的字值例子是:INTERVAL '150' MINUTE。

INTERVAL MINUTE TO SECOND类型

语法:INTERVAL MINUTE[(引导精度)] TO SECOND [(小数秒精度)]

功能:描述一个若干分钟若干秒的间隔,引导精度规定了分钟的取值范围。引导精度取值范围为1~9,如果未定义,缺省精度为2。小数秒精度规定了秒字段中小数点后面的位数,取值范围为0~6,如果未定义,缺省精度为6。例如:INTERVAL MINUTE(2) TO SECOND(1),其中MINUTE(2)表示分钟的精度为2,SECOND(1)表示秒的小数点后面取1位,表示范围为负99分零59.9秒到正99分零59.9秒。一个合适的字值例子是:INTERVAL
'12:01.1' MINUTE TO SECOND。

INTERVAL SECOND类型

语法:INTERVAL SECOND[(引导精度 [,小数秒精度] )]

功能:描述一个若干秒的间隔,引导精度规定了秒整数部分的取值范围。引导精度取值范围为1~9,如果未定义,缺省精度为2。小数秒精度规定了秒字段中小数点后面的位数,取值范围为0~6,如果未定义,缺省精度为6。例如:INTERVAL SECOND(2,1),表示范围为负99.9秒到正99.9秒。一个合适的字值例子是:INTERVAL '51.1' SECOND。

  1. 时区数据类型

DM支持两种时区类型:标准时区类型和本地时区类型。

(一) 标准时区类型:带时区的TIME类型和带时区的TIMESTAMP类型。

  1. TIME WITH TIME ZONE类型
语法:TIME[(小数秒精度)]WITH TIME ZONE

功能:描述一个带时区的TIME值,其定义是在TIME类型的后面加上时区信息。TIME值部分与1.4.3节1中的描述一致;时区部分的实质是INTERVAL
HOUR TO MINUTE类型,取值范围:-12:59与+14:00之间。例如:TIME '09:10:21 +8:00'。

DM支持SQL92标准或SQL SERVER的TIME WITH TIME ZONE字值,例如:TIME '09:10:21 +8:00', '09:10:21+8:00'或'9:10:21+8:00'都是有效的TIME WITH TIME ZONE值,且彼此等价。

例如:

CREATE TABLE T2(C1 TIME (2) WITH TIME ZONE);
INSERT INTO T2 VALUES(TIME '09:10:21 +8:00');
  1. TIMESTAMP WITH TIME ZONE类型
语法:TIMESTAMP[(小数秒精度)]WITH TIME ZONE

功能:描述一个带时区的TIMESTAMP值,其定义是在TIMESTAMP类型的后面加上时区信息。TIMESTAMP值部分与1.4.3节1中的描述一致,时区部分的实质是INTERVAL HOUR TO MINUTE类型,取值范围:-12:59与+14:00之间。例如:’2009-10-11 19:03:05.0000 -02:10’。

DM支持SQL92标准或SQL SERVER的TIMESTAMP字值,例如:TIMESTAMP '2002-12-12 09:10:21 +8:00'或'2002-12-12 9:10:21 +8:00'或'2002/12/12 09:10:21 +8:00'或'2002.12.12 09:10:21 +8:00' 都是有效的TIMESTAMP WITH TIME ZONE值,且彼此等价。

例如:

CREATE TABLE T2(C1 TIMESTAMP(2) WITH TIME ZONE);
INSERT INTO T2 VALUES(TIMESTAMP '2002-12-12 09:10:21 +8:00');

(二) 本地时区类型:本地时区的TIMESTAMP类型。

  1. TIMESTAMP WITH LOCAL TIME ZONE类型

语法:TIMESTAMP[(小数秒精度)]WITH LOCAL TIME ZONE

功能:描述一个本地时区的TIMESTAMP值,能够将标准时区类型TIMESTAMP WITH TIME ZONE类型转化为本地时区类型,如果插入的值没有指定时区,则默认为本地时区。

TIMESTAMP值部分与1.4.3节1中的描述一致,时区部分的实质是INTERVAL HOUR TO MINUTE类型,取值范围:-12:59与+14:00之间。例如:’2009-10-11 19:03:05.0000 -02:10’。

DM支持SQL92标准或SQL SERVER的TIMESTAMP字值,例如:TIMESTAMP '2002-12-12 09:10:21 +8:00'或'2002-12-12 9:10:21 +8:00'或'2002/12/12 09:10:21 +8:00'或'2002.12.12 09:10:21 +8:00' 都是有效的TIMESTAMP WITH LOCAL TIME ZONE值,且彼此等价。

例如:

CREATE TABLE T2(C1 TIMESTAMP(3) WITH LOCAL TIME ZONE,C2 TIMESTAMP(3) WITH LOCAL TIME ZONE );
INSERT INTO T2 VALUES(TIMESTAMP '2002-12-12 09:10:21 +8:00', TIMESTAMP '2002-12-12 09:10:21');
SELECT * FROM T2;

查询结果:

2002-12-12 09:10:21.000 2002-12-12 09:10:21.000

1.4.4 多媒体数据类型

多媒体数据类型的字值有两种格式:一是字符串,例如:’ABCD’,二是BINARY,如0x61626364。

TEXT、LONG、LONGVARCHAR、CLOB只支持字符串。

BFILE不适用上面两种格式。BFILE指明的文件只能只读访问。

不支持为多媒体数据类型的字段指定精度。

  1. TEXT类型
语法:TEXT

功能:TEXT为变长字符串类型。其字符串的长度最大为100G-1字节。DM利用它存储长的文本串。

  1. LONG、LONGVARCHAR(又名TEXT)类型
语法:LONG/LONGVARCHAR

功能:与TEXT相同。

  1. IMAGE类型
语法:IMAGE

功能:IMAGE用于指明多媒体信息中的图像类型。图像由不定长的象素点阵组成,长度最大为100G-1字节。该类型除了存储图像数据之外,还可用于存储任何其它二进制数据。

  1. LONGVARBINARY(又名IMAGE)类型
语法:LONGVARBINARY

功能:与IMAGE相同。

  1. BLOB类型
语法:BLOB

功能:BLOB类型用于指明变长的二进制大对象,长度最大为100G-1字节。

  1. CLOB类型
语法:CLOB

功能:CLOB类型用于指明变长的字母数字字符串,长度最大为100G-1字节。

  1. BFILE类型
语法:BFILE

功能:BFILE用于指明存储在操作系统中的二进制文件,文件存储在操作系统而非数据库中,仅能进行只读访问。

1.5 DM_SQL语言支持的表达式

DM支持多种类型的表达式,包括数值表达式、字符串表达式、时间值表达式、时间间隔值表达式等。本节中引用的数据库实例请参见第2章。

1.5.1 数值表达式

  1. 一元算符 + 和 -
语法:+exp 、-exp

(exp代表表达式,下同)
当单独使用时,+ 和 – 代表表达式的正负号。

select -(-5), +NOWPRICE from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

5 6.1000

注:在SQL中由于两短横即“--”,表示“注释开始”,则双负号必须是-(-5),而不是--5。

  1. 一元算符 ~
语法:~exp

按位非算符,要求参与运算的操作数都为整数数据类型。

select ~10 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

-11

  1. 二元算符 +、-、*、/
语法:exp1+exp2 、exp1- exp2 、exp1*exp2 、exp1/exp2

(exp1代表表达式1,exp2代表表达式2,下同)

当在表达式之间使用+、-、*、/时,分别表示加、减、乘、除运算。对于结果的精度规定如下:

  1. 只有精确数值数据类型的运算

两个相同类型的整数运算的结果类型不变,两个不同类型的整数运算的结果类型转换为范围较大的那个整数类型。

整数与NUMERIC,DEC等类型运算时,SMALLINT类型的精度固定为5,标度为0;INTEGER类型的精度固定为10,标度为0;BIGINT类型的精度固定为19,标度为0。

exp1+exp2结果的精度为二者整数部分长度(即精度-标度)的最大值与二者标度的最大值之和,标度是二者标度的最大值;

exp1-exp2结果的精度为二者整数部分长度的最大值与二者标度的最大值之和,标度是二者标度的最大值;

exp1*exp2结果的精度为二者的精度之和,标度也是二者的标度之和;

exp1/exp2结果为NUMERIC类型(缺省的精度为38,标度未限定)。

select NOWPRICE+1, NOWPRICE-1 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

7.1 5.1

select NOWPRICE*10, NOWPRICE/10 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

61 0.61

  1. 有近似数值数据类型的运算

对于exp1+exp2 、exp1- exp2 、exp1*exp2 、exp1/exp2中exp1和exp2只要有一个为近似数值数据类型,则结果为近似数值数据类型。

select NOWPRICE+3, NOWPRICE-3, NOWPRICE*3, NOWPRICE/3 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

9.1 3.1 18.3 2.0333333333333333333333333333333333334

  1. 二元算符 &
语法:exp1 & exp2

按位与算符,要求参与运算的操作数都为整数数据类型。

select 20 & 10 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

0

  1. 二元算符 |
语法:exp1 | exp2

按位或算符,要求参与运算的操作数都为整数数据类型。

select 20 | 10 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

30

  1. 二元算符 ^
语法:exp1 ^ exp2

按位异或算符,要求参与运算的操作数都为整数数据类型。

select 20 ^ 10 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

30

  1. 二元算符<<、>>
语法:exp1 << exp2
exp1 >> exp2

左移、右移运算符,要求参与运算的操作数只能为整数数据类型、精确数据类型。

select 1 << 3 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

8

select 8 >> 3 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

结果是:

1

当在表达式之间使用<<、>> 时,对于表达式exp1、exp2的类型规则如下:

  1. 只有整数数据类型的运算

左右操作数都为smallint、tinyint时操作结果为int类型;

左右操作数都为int类型时操作结果为int类型;

左右操作数都为bigint类型时操作结果为bigint类型。

左操作数是int、smallint、tinyint类型,右操作数为int、smallint、tinyint类型时,操作结果为范围较大的类型。

当左操作数或右操作数有一个是bigint类型时,操作结果为bigint类型。

  1. 有精确数据类型的运算:

当左操作数、右操作数都是精确数据类型时,分别四舍五入转化成bigint类型后运算,结果为bigint类型;

当整数与精确数据类型运算时,将精确数据类型四舍五入转化成bigint类型后运算,结果为bigint类型。

  1. 有字符串数据类型的运算

字符串指数字字符串,不支持字符串与字符串运算;

当整数与数字字符串数据类型运算时,结果为整数数据类型;

当精确数据类型与字符串数据类型运算时,结果为bigint类型。

1.5.2 字符串表达式

连接 ||

语法:STR1 || STR2

(STR1代表字符串1,STR2代表字符串2)

连接操作符对两个运算数进行运算,其中每一个都是对属于同一字符集的字符串的求值。它以给定的顺序将字符串连接在一起,并返回一个字符串。其长度等于两个运算数长度之和。如果两个运算数中有一个是NULL,则NULL等价为空串。

select '武汉' || ADDRESS1 from PERSON.ADDRESS WHERE ADDRESSID=3;

结果是:

武汉青山区青翠苑1号

1.5.3 时间值表达式

时间值表达式的结果为时间值类型,包括日期(DATE)类型,时间(TIME)类型和时间戳(TIMESTAMP)间隔类型。DM SQL不是对于任何的日期时间和间隔运算数的组合都可以计算。如果任何一个运算数是NULL,运算结果也是NULL。下面列出了有效的可能性和结果的数据类型。

  1. 日期+间隔,日期-间隔和间隔+日期,得到日期

日期表达式的计算是根据有效格里高利历日期的规则。如果结果是一个无效的日期,表达式将出错。参与运算的间隔类型只能是INTERVAL YEAR、INTERVAL MONTH、INTERVAL YEAR TO MONTH、INTERVAL DAY。

如果间隔运算数是年-月间隔,则没有从运算数的DAY字段的进位。

select PUBLISHTIME + INTERVAL '1' YEAR, PUBLISHTIME - INTERVAL '1' YEAR
from PRODUCTION.PRODUCT
where PRODUCTID=1;

结果是:

2006-04-01 2004-04-01<44444>

  1. 时间+间隔,时间-间隔和间隔+时间,得到时间

时间表达式的计算是根据有效格里高利历日期的规则。如果结果是一个无效的时间,表达式将出错。参与运算的间隔类型只能是INTERVAL DAY、INTERVAL HOUR、INTERVAL MINUTE、INTERVAL SECOND、INTERVAL DAY TO HOUR、INTERVAL DAY TO MINUTE、INTERVAL DAY TO SECOND、INTERVAL HOUR TO MINUTE、INTERVAL HOUR TO SECOND、INTERVAL MINUTE TO SECOND。

当结果的小时值大于等于24时,时间表达式是对24模的计算。

SELECT TIME '19:00:00'+INTERVAL '9' HOUR,
TIME '19:00:00'-INTERVAL '9' HOUR;

结果是:

04:00:00 10:00:00

  1. 时间戳记+间隔,时间戳记-间隔和间隔+时间戳记,得到时间戳记

时间戳记表达式的计算是根据有效格里高利历日期的规则。如果结果是一个无效的时间戳记,表达式将出错。参与运算的间隔类型只能是INTERVAL YEAR、INTERVAL MONTH、INTERVAL YEAR TO MONTH、INTERVAL DAY、INTERVAL HOUR、INTERVAL MINUTE、INTERVAL SECOND、INTERVAL DAY TO HOUR、INTERVAL DAY TO MINUTE、INTERVAL DAY TO SECOND、INTERVAL HOUR TO MINUTE、INTERVAL HOUR TO SECOND、INTERVAL MINUTE TO SECOND。

与时间的计算不同,当结果的小时值大于等于24时,结果进位到天。

SELECT TIMESTAMP'2007-07-15 19:00:00'+INTERVAL'9'HOUR,TIMESTAMP'2007-07-15 19:00:00'-INTERVAL'9'HOUR;

结果是:

2007-07-16 04:00:00 2007-07-15 10:00:00

注:在含有SECOND值的运算数之间的一个运算的结果具有等于运算数的小数秒精度的小数秒精度。

  1. 日期+数值,日期-数值和数值+日期,得到日期

日期与数值的运算,等价于日期与一个INTERVAL ‘数值’ DAY的时间间隔的运算。

SELECT CURDATE();

结果是:

2011-09-29 /* 假设该查询操作发生在2011年9月29日 */

SELECT CURDATE() + 2;

结果是:

2011-10-01

SELECT CURDATE() - 100;

结果是:

2011-06-21

  1. 时间戳记+数值,时间戳记-数值和数值+时间戳记,得到时间戳记

时间戳记与数值的运算,将数值看作以天为单位,转化为一个INTERVAL DAY TO SECOND(6)的时间间隔,然后进行运算。

例 时间戳加上2.358天。

SELECT TIMESTAMP '2003-09-29 08:59:59.123' + 2.358;

结果是:

2003-10-01 17:35:30.323000

1.5.4 时间间隔值表达式

  1. 日期-日期,得到间隔

由于得到的结果可能会是“年-月-日”间隔,而这是不支持的间隔类型,故要对结果强制使用语法:

(日期表达式-日期表达式)<时间间隔限定符>

结果由<时间间隔限定符>中最不重要的日期字段决定。

SELECT (PUBLISHTIME-DATE'1990-01-01')YEAR TO MONTH FROM PRODUCTION.PRODUCT WHERE PRODUCTID=1;

结果是:

INTERVAL '15-3' YEAR(9) TO MONTH

  1. 时间-时间,得到间隔

要对结果强制使用语法:

(时间表达式-时间表达式)<时间间隔限定符>

结果由<时间间隔限定符>中最不重要的时间字段决定。

SELECT (TIME'19:00:00'-TIME'10:00:00') HOUR;

结果是:

INTERVAL '9' HOUR(9)

  1. 时间戳记 - 时间戳记,得到间隔

要对结果强制使用语法:

(时间戳记表达式-时间戳记表达式)<时间间隔限定符>

结果由<时间间隔限定符>中最不重要的日期时间字段决定。

SELECT (TIMESTAMP '2007-07-15 19:00:00'- TIMESTAMP '2007-01-15 19:00:00') HOUR;

结果是:

INTERVAL '4344' HOUR(9)

  1. 年月间隔 + 年月间隔和年月间隔 - 年月间隔,得到年月间隔

参加运算的两个间隔必须有相同的数据类型,若得出无效的间隔的表达式将出错。结果的子类型包括运算数子类型所有的域,关于结果的引导精度规定如下:

如果二者的子类型相同,则为二者引导精度的最大值;如果二者的子类型不同,则为与结果类型首字段相同的那个运算数的引导精度。

SELECT INTERVAL'2007-07'YEAR(4) TO MONTH + INTERVAL'7'MONTH,
INTERVAL'2007-07'YEAR(4) TO MONTH - INTERVAL'7'MONTH;

结果是:

INTERVAL '2008-2' YEAR(9) TO MONTH INTERVAL '2007-0' YEAR(9) TO MONTH

  1. 日时间隔 + 日时间隔和日时间隔 - 日时间隔,得到日时间隔

参加运算的两个间隔必须有相同的数据类型,若得出无效的间隔表达式将出错。结果的子类型包含运算数子类型所有的域,结果的小数秒精度为两运算数的小数秒精度的最大值,关于结果的引导精度规定如下:

如果二者的子类型相同,则为二者引导精度的最大值;如果二者的子类型不同,则为与结果类型首字段相同的那个运算数的引导精度。

SELECT INTERVAL'7 15'DAY TO HOUR + INTERVAL'10:10'MINUTE TO SECOND,

INTERVAL'7 15'DAY TO HOUR - INTERVAL'10:10'MINUTE TO SECOND;

结果是:

INTERVAL '7 15:10:10.000000' DAY(9) TO SECOND(6)

INTERVAL '7 14:49:50.000000' DAY(9) TO SECOND(6)

  1. 间隔 * 数字,间隔 / 数字和数字 * 间隔,得到间隔

若得出无效的间隔表达式将出错。结果的子类型、小数秒精度、引导精度和原间隔相同。

SELECT INTERVAL'10:10'MINUTE TO SECOND * 3,
INTERVAL'10:10'MINUTE TO SECOND / 3;

结果是:

INTERVAL '30:30.000000' MINUTE(9) TO SECOND(6)

INTERVAL '3:23.333333' MINUTE(9) TO SECOND(6)

1.5.5 运算符的优先级

当一个复杂的表达式有多个运算符时,运算符优先性决定执行运算的先后次序。运算符有下面这些优先等级(从高到低排列)。在较低等级的运算符之前先对较高等级的运算符进行求值。

( )
+(一元正)、-(一元负)、~(一元按位非)
*(乘)、/(除)
+(加)、-(减)
|| (串联)
^(按位异)、&(按位与)、|(按位或)

1.6 DM_SQL语言支持的数据库模式

DM_SQL语言支持关系数据库的三级模式,外模式对应于视图和部分基表,模式对应于基表,基表是独立存在的表。一个或若干个基表存放于一个存贮文件中,存贮文件中的逻辑结构组成了关系数据库的内模式。DM_SQL语言本身不提供对内模式的操纵语句。

视图是从基表或其它视图上导出的表,DM只将视图的定义保存在数据字典中。该定义实际为一查询语句,再为该查询语句取一名字即为视图名。每次调用该视图时,实际上是执行其对应的查询语句,导出的查询结果即为该视图的数据。所以视图并无自己的数据,它是一个虚表,其数据仍存放在导出该视图的基表之中。当基表中的数据改变时,视图中查询的数据也随之改变,因此,视图象一个窗口,用户透过它可看到自己权限内的数据。视图一旦定义也可以为多个用户所共享,对视图作类似于基表的一些操作就像对基表一样方便。

综上所述,SQL语言对关系数据库三级模式的支持如下图所示。

关系数据库的三级模式

微信扫码
分享文档
扫一扫
联系客服