-DM数据库学习之路(四)DM8数据库SQL基础及SQL语句测试

  1. DM8_SQL概述
    1. DM_SQL简介

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

  • 功能一体化

DM_SQL 支持多媒体数据类型,用户在建表时可直接使用。DM 系统在处理常规数据与多媒体数据时达到了四个一体化:一体化定义、一体化存储、一体化检索、一体化处理,最大限度地提高了数据库管理系统处理多媒体的能力和速度;

DM_SQL 语言集数据库的定义、查询、更新、控制、维护、恢复、安全等一系列操作于一体,每一项操作都只需一种操作符表示,格式规范,风格一致,简单方便,很容易为用户所掌握。

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

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

高度非过程化

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

面向集合的操作方式

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

语言简洁,方便易学

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

1.2 保留字与标识符

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

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

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

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

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

在兼容 MYSQL 的模式下,定界标识符的标识符体除用双引号括起来外,还支持使用反引号`进行定界或关键字的转义。如`TABLE_NAME`,`test`。

​​​​​​​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 适用范围

适用于所有技术人员,数据库爱好者,数据库初学者。 

  1. DM8_SQL数据类型
    1. DM_SQL 所支持的数据类型

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

    1. 常规数据类型
      1. 字符数据类型
  1. CHAR 类型
语法:CHAR[(长度)]

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

数据库页面大小

实际最大长度

4 K

1900

8 K

3900

16 K

8000

32 K

8188

  1. CHARACTER 类型

语法:CHARACTER[(长度)]

功能:与 CHAR 相同。

  1. VARCHAR 类型/VARCHAR2 类型

语法:VARCHAR[(长度 [CHAR])]

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

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

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

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

  1. ROWID 类型

语法:ROWID

功能:ROWID 类型数据由 18 位字符组成,用来表示 ROWID 数据。18 位字符由“4 位站点号 +6 位分区号 +8 位物理行号”组成。ROWID 类型数据可通过 SF_BUILD_ROWID() 构造而来。

表中的 ROWID 类型列,可以用于排序或创建索引。但是 ROWID 类型不支持作为分区列和自定义类型的属性数据类型。ROWID 列与字符类型一样,支持 MAX,MIN 等集函数,不支持 SUM,AVG 等集函数。

      1. 数值数据类型

精确数值数据类型

  1. NUMERIC 类型

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

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

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

  1. DECIMAL 类型

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

功能:与 NUMERIC 相似。

  1. DEC 类型

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

功能:与 DECIMAL 相同。

  1. NUMBER 类型

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

功能:与 NUMERIC 相同。

  1. INTEGER 类型

语法:INTEGER

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

  1. INT 类型

语法:INT

功能:与 INTEGER 相同。

  1. BIGINT 类型

语法:BIGINT

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

  1. TINYINT 类型

语法:TINYINT

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

  1. BYTE 类型

语法:BYTE

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

  1. SMALLINT 类型

语法:SMALLINT

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

  1. BINARY 类型

语法:BINARY[(长度)]

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

  1. VARBINARY 类型

语法:VARBINARY[(长度)]

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

  1. RAW 类型

语法:RAW[(长度)]

功能:与 VARBINARY 相同。

近似数值数据类型

  1. FLOAT 类型

语法:FLOAT[(精度)]

功能:FLOAT 是带二进制精度的浮点数,精度范围(1~126)。当精度小于等于 24 时,DM 将其转换为标准 C 语言中的 REAL 类型;当精度大于 24 时,转换为标准 C 语言中的 DOUBLE 类型。

FLOAT 取值范围-1.7*10^308 ~ 1.7*10^308。

  1. DOUBLE 类型

语法:DOUBLE[(精度)]

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

  1. REAL 类型

语法:REAL

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

  1. DOUBLE PRECISION 类型

语法:DOUBLE PRECISION[(精度)]

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

      1. 位串数据类型
  1. BIT 类型

语法:BIT

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

功能与 ODBC 和 JDBC 的 BOOL 相同。

      1. 日期时间数据类型

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

一般日期时间数据类型

  1. DATE 类型

语法:DATE

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

DATE 值的书写方式有两种:一是 DATE'年月日';二是'年月日'。其中,年月日之间可以使用分隔符或者没有分隔符。分隔符是指除大小写字母、数字以及双引号之外的所有单字节字符且是可打印的。例如: 空格、回车键、tab 键、- / , . : *等标点符号。年月日中第一个非 0 数值前的 0 亦可省略,例如:'0001-01-01'等价于'1-1-1'。

例如:

CREATE TABLE T2(C1 DATE,C2 DATE,C3 DATE );

INSERT INTO T2 VALUES(DATE '1999-10-01','1999/10/01','1999.10.01');

  1. TIME 类型

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

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

TIME 值的书写方式有两种:一是 TIME'时:分:秒';二是'时:分:秒'。

例如:

CREATE TABLE T2(C1 TIME(2),C2 TIME,C3 TIME);

INSERT INTO T2 VALUES(TIME '09:10:21.20','09:10:21','9:10:21.49');

  1. TIMESTAMP 类型

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

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

TIMESTAMP 值的书写方式有两种:一是 TIMESTAMP'

例如:

CREATE TABLE T2(C1 TIMESTAMP,C2 DATETIME,C3 TIMESTAMP,C4 DATETIME,C5 TIMESTAMP);

INSERT INTO T2 VALUES(TIMESTAMP '2002-12-12 09:10:21',TIMESTAMP '2002-12-12 09:10:21','2002/12/12 09:10:21','2002.12.12 09:10:21',DATETIME'2002-12-12 09:10:21' );

时间间隔数据类型

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

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

(一) 年-月间隔类

  1. INTERVAL YEAR TO MONTH 类型

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

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

  1. INTERVAL YEAR 类型

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

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

  1. 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。

  1. 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。

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

  1. 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。

  1. INTERVAL HOUR 类型

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

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

  1. 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。

  1. 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。

  1. INTERVAL MINUTE 类型

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

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

  1. 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。

  1. INTERVAL SECOND 类型

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

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

时区数据类型

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 WITH TIME ZONE 值的书写方式有两种:一是 TIME'时分秒 < 时区 >';二是'时分秒 < 时区 >'。

例如:

CREATE TABLE T2(C1 TIME (2) WITH TIME ZONE,C2 TIME (2) WITH TIME ZONE);

INSERT INTO T2 VALUES(TIME '09:10:21 +8:00','09:10:21 -11:00');

TIMESTAMP WITH TIME ZONE 类型

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

功能:描述一个带时区的 TIMESTAMP 值,其定义是在 TIMESTAMP 类型的后面加上时区信息。TIMESTAMP 值部分与一般日期时间数据类型中的描述一致,时区部分的实质是 INTERVAL HOUR TO MINUTE 类型,取值范围:-12:59 与 +14:00 之间。

TIMESTAMP WITH TIME ZONE 值的书写方式有两种:一是 TIMESTAMP'

例如:

CREATE TABLE T2(C1 TIMESTAMP(2) WITH TIME ZONE,C2 TIMESTAMP(2) WITH TIME ZONE,C3 TIMESTAMP(2) WITH TIME ZONE,C4 TIMESTAMP(2) WITH TIME ZONE);

INSERT INTO T2 VALUES(TIMESTAMP '2002-12-12 09:10:21 +8:00','2002-12-12 9:10:21 +9:00','2002/12/12 09:10:21 -10:00','2002.12.12 09:10:21 -5:00');

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

  1. TIMESTAMP WITH LOCAL TIME ZONE 类型

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

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

TIMESTAMP 值部分与一般日期时间数据类型 中的描述一致,时区部分的实质是 INTERVAL HOUR TO MINUTE 类型,取值范围:-12:59 与 +14:00 之间。

TIMESTAMP WITH LOCAL TIME ZONE 值的书写方式有两种:一是 TIMESTAMP'

例如:

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. 多媒体数据类型

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

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

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

BINARY 格式的多媒体数据类型以及 BFILE 数据类型不支持比较。

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

  1. TEXT 类型

语法:TEXT

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

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

功能:与 TEXT 相同。

  1. BFILE 类型

语法:BFILE

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

只列取了部分DM8支持的常规数据类型,更多的数据类型请参考达梦官网。

    1. DM_SQL 语言支持的表达式

DM 支持多种类型的表达式,包括数值表达式、字符串表达式、时间值表达式、时间间隔值表达式等。

      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

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

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

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

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

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

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

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

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

例 1 使用 +、-运算

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

查询结果为:7.1 5.1

例 2 使用*、/运算

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

查询结果为:61 0.61

例 3 使用 % 运算

select NOWPRICE%4 from PRODUCTION.PRODUCT WHERE NOWPRICE<10;

查询结果为:2.1

2)有近似数值数据类型的运算

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

例如:

drop table TEST;

create table TEST(C1 int, C2 double);

insert into TEST values(5, 3.3);

select C1-C2, C1/C2 from TEST;

查询结果为:1.700000000000000E+00 1.515151515151515E+00

  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

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

例 1 左移运算符的使用

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

查询结果为:8

例 2 右移运算符的使用

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 类型。

2)有精确数据类型的运算:

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

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

3)有字符串数据类型的运算

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

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

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

      1. 字符串表达式

连接 ||

语法:STR1 || STR2

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

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

例如:

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

查询结果为:武汉青山区青翠苑 1 号

      1. 时间值表达式

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

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

日期表达式的计算是根据有效格里高利历日期的规则。如果结果是一个无效的日期,表达式将出错。参与运算的间隔类型只能是 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>

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

时间表达式的计算是根据有效格里高利历日期的规则。如果结果是一个无效的时间,表达式将出错。参与运算的间隔类型只能是 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。

例 对时间值进行 +、-小时间隔运算。

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

查询结果为:04:00:00 10:00:00

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

时间戳记表达式的计算是根据有效格里高利历日期的规则。如果结果是一个无效的时间戳记,表达式将出错。参与运算的间隔类型只能是 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 值的运算数之间的一个运算的结果具有等于运算数的小数秒精度的小数秒精度。

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

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

例 1 未设置 + 或-的数值时返回操作发生的日期

SELECT CURDATE(); //假设该查询操作发生在2011年9月29日

查询结果为:2011-09-29

例 2 返回当前日期 + 数值后的结果

SELECT CURDATE() + 2;

查询结果为:2011-10-01

例 3 返回当前日期-数值的结果

SELECT CURDATE() - 100;

查询结果为:2011-06-21

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

时间戳记与数值的运算,将数值看作以天为单位,转化为一个 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

时间戳支持使用 AT TIME ZONE 语法进行时区转换,得到带时区的时间戳记

对于时间戳数据或返回值为时间戳的表达式,可以使用 AT TIME ZONE < 转换表达式 > 进行时区转换。

< 转换表达式 > 可以设置为:

  • 时区偏移量:格式为'(+|-)HH:MM',指定一个时区作为标准时区(UTC)的偏移量。例如'+8:00'表示比 UTC 早 8 个小时的时区。
  • DBTIMEZONE:DM 在创建时设置(指定或默认)的数据库所用时区,DM 默认使用的是‘+8:00’时区。
  • SESSIONTIMEZONE:当前会话设置的时区。默认为数据库时区,设置了则为在最近的 ALTER SESSION 语句中建立的会话时区。
  • 时区地区名:指定一个时区地区名称,数据库会返回对应时区地区名的时区的值。例如,可以指定为'Asia/Hong_Kong'。
  • 表达式:若为一个返回具有有效时区格式的字符串,则数据库返回对应时区的值;若不为有效时区格式,则数据库报错。

例 1 指定时区偏移量为'-3:00'。

SELECT TIMESTAMP '2023-06-01 18:05:23.234 +08:00' AT TIME ZONE '-3:00' FROM DUAL;;

查询结果为:2023-06-01 07:05:23.234000 -03:00

例 2 指定时区地区名为‘Africa/Lusaka’。

SELECT FROM_TZ(CAST(SYSDATE AS TIMESTAMP), TZ_OFFSET('Asia/Shanghai')) AT TIME ZONE 'America/Los_Angeles' AS ZANBIYA FROM DUAL;

查询结果为:2023-07-26 20:41:16.000000 -07:00

      1. 时间间隔值表达式
  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. 运算符的优先级

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

( )

+(一元正)、-(一元负)、~(一元按位非)

*(乘)、/(除)、%(取余数)

+(加)、-(减)

|| (串联)

<<(左移)、>>(右移)

&(按位与)

^(按位异)

|(按位或)

    1. DM_SQL 语言支持的数据库模式

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

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

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

-DM数据库学习之路(四)DM8数据库SQL基础及SQL语句测试_第1张图片

  1. DM8增删改查测试
    1. 测试数据准备
      1. 建表空间及用户

dm8db01>$disql SYSDBA/[email protected]:5236

-- 创建表空间(缓冲区类型为 NORMAL)

SQL>create tablespace "OMP_TS" datafile '/dm8/data/CUGDB/OMPTS01.DBF' size 128 autoextend on next 1 maxsize 200 CACHE = NORMAL;

alter tablespace OMP_TS add  datafile '/dm8/data/CUGDB/OMPTS02.DBF' size 128 autoextend on next 1 maxsize 200;

alter tablespace OMP_TS add  datafile '/dm8/data/CUGDB/OMPTS03.DBF' size 128 autoextend on next 1 maxsize 200;

-- 创建用户及授权

CREATE USER omp IDENTIFIED BY "omp123123!" DEFAULT TABLESPACE OMP_TS;

-- 密码时效不做限制

alter user "omp" limit  password_lock_time unlimited;

-- 授权

GRANT RESOURCE TO omp;

-- omp用户登录

SQL> conn omp/"omp123123!"

或者

disql omp/"omp123123!"@127.0.0.1:5237

      1. 建测试数据

create table year_2001(

ID            number(10) primary key not null,            

name       varchar2(30),

port    VARCHAR(255),

speed    VARCHAR(255),

type    VARCHAR(255),

create_time     date

);

begin

for i in 1..20 loop

insert into year_2001 values(i, 'cisco-'||i,'3306','10000','router-'||i,to_date('2021-06-20 18:31:34','YYYY-MM-DD HH24:MI:SS'));

end loop;

commit;

end;

/

begin

for i in 21..40 loop

insert into year_2001 values(i, 'cisco-'||i,'3306','10000','router-'||i,to_date('2021-06-21 23:51:49','YYYY-MM-DD HH24:MI:SS'));

end loop;

commit;

end;

/

begin

for i in 41..50 loop

insert into year_2001 values(i, 'cisco-'||i,'3306','10000','router-'||i,to_date('2021-06-22 08:31:49','YYYY-MM-DD HH24:MI:SS'));

end loop;

commit;

end;

/

SQL> select TABLE_NAME from user_tables;

LINEID     TABLE_NAME

---------- ----------

year_2001

SQL> select count(*) from year_2001;

LINEID     COUNT(*)           

---------- --------------------

50

      1. 增删改查测试

dm8db01>$disql omp/'omp123123!'@127.0.0.1:5236

--建索引

SQL> create index year2001_index on year_2001(id);

--增加(insert)

insert into year_2001 values(51, 'cisco-51','3306','10000','router-51',to_date('2021-06-20 18:31:34','YYYY-MM-DD HH24:MI:SS'));

--删除(delete,truncate)

SQL> delete from year_2001 where id >=48 and id <=50;

--修改(update)

SQL> update year_2001 set name='cisco-555' where id=51;

--查询(select)

SQL> select count(*) from omp.year_2001;

      1. 建视图

视图是从一个或几个基表(或视图)导出的表,它是一个虚表,即数据字典中只存放视图的定义(由视图名和查询语句组成),而不存放对应的数据,这些数据仍存放在原来的基表中。当需要使用视图时,则执行其对应的查询语句,所导出的结果即为视图的数据。因此当基表中的数据发生变化时,从视图中查询出的数据也随之改变了,视图就像一个窗口,透过它可以看到数据库中用户感兴趣的数据和变化。由此可见,视图是关系数据库系统提供给用户以多种角度观察数据库中数据的重要机制,体现了数据库本身最重要的特色和功能,它简化了用户数据模型,提供了逻辑数据独立性,实现了数据共享和数据的安全保密。视图是数据库技术中一个十分重要的功能。

视图一经定义,就可以和基表一样被查询、修改和删除,也可以在视图之上再建新视图。由于对视图数据的更新均要落实到基表上,因而操作起来有一些限制,读者应注意如何才能在视图中正确更新数据。

SQL> create view view_year_2001 as select * from year_2001;

SQL> select * from view_year_2001;

      1. 建物化视图

物化视图是从一个或几个基表导出的表,同视图相比,它存储了导出表的真实数据。当基表中的数据发生变化时,物化视图所存储的数据将变得陈旧,用户可以通过手动刷新或自动刷新来对数据进行同步。

SQL> CREATE MATERIALIZED VIEW  mv_year_2001 REFRESH WITH ROWID START WITH SYSDATE NEXT SYSDATE + 1 AS select * from year_2001;

SQL> select count(*) from mv_year_2001;

行号     COUNT(*)           

---------- --------------------

  1. 51
    1. 表管理测试
      1. 数据类型测试

步骤

目的和动作

预期测试结果

1

--连接数据库成功后,执行如下SQL命令

create table test1 (c1 int, c2 char(10), c3varchar, c4 numeric(5,2), c5 smallint, c6 bigint, c7 byte,c8 binary,c9 float, c10 double, c11 real,c12 bit,c13 date,c14 time, c15 timestamp, c16 interval year to month,  c17 time with time zone, c18 text,c19 image ,c20 blob, c21 clob);

表对象创建成功

2

--插入一行数据,执行如下SQL命令

insert into test1 values (1, 'abcd', 'testdatatype', '-123.45', '-32768', '-92233720', 123, '1', 5, 7.8, 9.1, null, '2012-12-24', '21:59:59', '2012-12-21 07:59:59', '15-08', '19:59:59 +02:03', 'test text data type','0x123456789','0x987654321','test clob data type');

commit;

插入数据成功

      1. 自增列测试

步骤

目的和动作

预期测试结果

1

--连接数据库成功后,执行如下SQL命令

create table TEST2(c1 int identity(1,2), c2 char);

表对象创建成功

2

--插入两行数据,执行如下SQL命令

insert into TEST2(c2) values('a');

insert into TEST2(c2) values('b');

commit;

插入数据成功

3

--查询数据,执行如下SQL命令

select * from TEST2;

返回结果集如下

1 a

3b

4

--查询种子值,执行如下SQL命令

select IDENT_SEED('SYSDBA.TEST2');

返回结果集如下

1

5

--查询增量值,执行如下SQL命令

select IDENT_INCR('SYSDBA.TEST2');

返回结果集如下

2

      1. 修改表测试

步骤

目的和动作

预期测试结果

1

--连接数据库成功后,执行如下SQL命令

CREATE TABLE TEST3 (c1 int primary key,c2 varchar(10) );

表对象创建成功

2

--修改表定义,执行如下SQL命令

alter table TEST3 add column SEX varchar(10);

执行修改成功

3

--插入一行数据,执行如下SQL命令

insert into TEST3 values(10,'ABC','male');

commit;

插入数据成功

4

--查询表中的数据,执行如下SQL命令

Select * from TEST3;

返回结果集如下

10  ABC  male

    1. 分区表测试
      1. 创建范围分区

步骤

目的和动作

预期测试结果

1

--连接数据库成功后,执行如下SQL命令

create table year_2002 (

ID int primary key not null,

name  varchar2(30),

port  VARCHAR2(20),

speed VARCHAR2(20),

type  VARCHAR2(50),

create_time date)

partition by range(create_time)(

partition p1 values less than ('2023-3-1'),

partition p2 values less than ('2023-6-1'),

partition p3 values less than ('2023-9-1'),

partition p4 values less than (maxvalue));

表对象创建成功

2

--插入数据,执行如下SQL命令

begin

for i in 1..5 loop

insert into year_2002 values(i, 'cisco-'||i,'3306','10000','router-'||i,to_date('2023-01-20 18:31:34','YYYY-MM-DD HH24:MI:SS'));

end loop;

commit;

end;

/

begin

for i in 6..10 loop

insert into year_2002 values(i, 'cisco-'||i,'3306','10000','router-'||i,to_date('2023-03-25 23:51:49','YYYY-MM-DD HH24:MI:SS'));

end loop;

commit;

end;

/

begin

for i in 11..17 loop

insert into year_2002 values(i, 'cisco-'||i,'3306','10000','router-'||i,to_date('2023-06-19 08:31:25','YYYY-MM-DD HH24:MI:SS'));

end loop;

commit;

end;

/

begin

for i in 12..20 loop

insert into year_2002 values(i, 'cisco-'||i,'3306','10000','router-'||i,to_date('2023-09-15 10:14:31','YYYY-MM-DD HH24:MI:SS'));

end loop;

commit;

end;

/

begin

for i in 21..26 loop

insert into year_2002 values(i, 'cisco-'||i,'3306','10000','router-'||i,to_date('2023-12-28 14:17:25','YYYY-MM-DD HH24:MI:SS'));

end loop;

commit;

end;

/

插入数据成功

3

--查询分区

select * from year_2002 partition(p1);

select * from year_2002 partition(p2);

select * from year_2002 partition(p3);

select * from year_2002 partition(p4);

      1. 创建哈希分区

步骤

目的和动作

预期测试结果

1

--连接数据库成功后,执行如下SQL命令

create table year_2003(c1 int , c2 varchar(10))

partition by hash(c1)(

partition p1 ,

partition p2 ,

partition p3

);

表对象创建成功

2

--插入数据,执行如下SQL命令

insert into YEAR_2003 values(1, 'a');

insert into YEAR_2003 values( 2, 'b');

insert into YEAR_2003 values( 3, 'c');

insert into YEAR_2003 values( 4, 'd');

insert into YEAR_2003 values( 5, 'e');

insert into YEAR_2003 values( 6, 'f');

插入数据成功

3

--查询哈希分区表,执行如下SQL命令

SELECT * FROM YEAR_2003 PARTITION (p3);

返回结果集如下

C1  C2

2b

5e

    1. left join及函数测试
      1. 创建学生表

CREATE TABLE student

(

student_id  NUMBER(15) NOT NULL COMMENT '学号',

name        VARCHAR(50) NOT NULL COMMENT '姓名',

sex         VARCHAR(2) NOT NULL COMMENT '性别0女1男',

age         NUMBER(3) NOT NULL COMMENT '年龄',

PRIMARY KEY (student_id)

);

添加表注释:

COMMENT ON TABLE student is '学生表';

手工添加字段注释:

COMMENT ON COLUMN student.student_id IS ‘学号’;

COMMENT ON COLUMN student.name IS ‘姓名’;

COMMENT ON COLUMN student.sex IS ‘性别0女1男’;

COMMENT ON COLUMN student.age IS ‘年龄’;

      1. 创建分数表

CREATE TABLE score (

student_id NUMBER(30) NOT NULL COMMENT '学号',

chinese_score NUMBER(11) NOT NULL COMMENT '语文',

math_core NUMBER(11) NOT NULL COMMENT '数学',

engline_score NUMBER(11) NOT NULL COMMENT '英语',

class_id NUMBER(30) NOT NULL COMMENT '班级ID',

PRIMARY KEY (student_id)

);

添加表注释:

COMMENT ON TABLE score is '分数表';

      1. 创建班级表

CREATE TABLE class (

class_id NUMBER(30) NOT NULL COMMENT '班级ID',

name VARCHAR(50) NOT NULL COMMENT '班级',

grade VARCHAR(50) NOT NULL COMMENT '年级',

PRIMARY KEY (class_id)

);

添加表注释:

COMMENT ON TABLE class is '班级表';

      1. 插入学生表数据

INSERT INTO student (student_id,name,sex,age) VALUES

(20231501001,'小明',1,6),

(20231501002,'小红',0,7),

(20231501003,'小刚',1,6),

(20231501004,'小丽',0,8),

(20231501005,'小花',0,6),

(20231501006,'小张',0,9),

(20231501007,'小刘',1,6),

(20231501008,'小马',1,7),

(20231501009,'小王',0,7),

(20231501010,'小李',0,8);

commit;

--0

--1

      1. 插入分数数据

INSERT INTO score (student_id,chinese_score,math_core,engline_score,class_id) VALUES

(20231501001,80,90,50,101),

(20231501002,90,68,58,102),

(20231501003,85,100,99,103),

(20231501004,95,97,98,201),

(20231501005,88,96,72,202),

(20231501006,82,96,82,301),

(20231501007,71,72,71,302),

(20231501008,78,93,78,401),

(20231501009,63,86,77,501),

(20231501010,54,94,75,601);

commit;

      1. 插入班级数据

INSERT INTO class (class_id,name,grade) VALUES

(101,'一班','一年级'),

(102,'二班','一年级'),

(103,'三班','一年级'),

(201,'一班','二年级'),

(202,'二班','二年级'),

(301,'一班','三年级'),

(302,'二班','三年级'),

(401,'一班','四年级'),

(501,'一班','五年级'),

(601,'一班','六年级');

commit;

      1. 查询所有学生

SQL> select * from student;

LINEID     student_id  name   sex age

---------- ----------- ------ --- ---

1          20231501001 小明 1   6

2          20231501002 小红 0   7

3          20231501003 小刚 1   6

4          20231501004 小丽 0   8

5          20231501005 小花 0   6

6          20231501006 小张 0   9

7          20231501007 小刘 1   6

8          20231501008 小马 1   7

9          20231501009 小王 0   7

10         20231501010 小李 0   8

      1. 查询所有分数

SQL> select * from score;

LINEID     student_id  chinese_score math_core engline_score class_id

---------- ----------- ------------- --------- ------------- --------

1          20231501001 80            90        50            101

2          20231501002 90            68        58            102

3          20231501003 85            100       99            103

4          20231501004 95            97        98            201

5          20231501005 88            96        72            202

6          20231501006 82            96        82            301

7          20231501007 71            72        71            302

8          20231501008 78            93        78            401

9          20231501009 63            86        77            501

10         20231501010 54            94        75            601

      1. 查询所有班级

SQL>  select * from class;

LINEID     class_id name   grade   

---------- -------- ------ ---------

1          101      一班 一年级

2          102      二班 一年级

3          103      三班 一年级

4          201      一班 二年级

5          202      二班 二年级

6          301      一班 三年级

7          302      二班 三年级

8          401      一班 四年级

9          501      一班 五年级

10         601      一班 六年级

      1. left join所有字段查询

SQL> SELECT a.student_id,a.name,b.chinese_score,b.math_core,b.engline_score,b.class_id FROM student a

left join  score b ON a.student_id = b.student_id

left join class c on c.class_id=b.class_id;

LINEID     student_id  name   chinese_score math_core engline_score class_id

---------- ----------- ------ ------------- --------- ------------- --------

1          20231501001 小明 80            90        50            101

2          20231501002 小红 90            68        58            102

3          20231501003 小刚 85            100       99            103

4          20231501004 小丽 95            97        98            201

5          20231501005 小花 88            96        72            202

6          20231501006 小张 82            96        82            301

7          20231501007 小刘 71            72        71            302

8          20231501008 小马 78            93        78            401

9          20231501009 小王 63            86        77            501

10         20231501010 小李 54            94        75            601

      1. left join指定字段别名查询

SQL> SELECT a.student_id as "学号",a.name as "姓名",b.chinese_score as "语文",b.math_core as "数学",b.engline_score as "英语",b.class_id as "班级" FROM student a

left join  score b ON a.student_id = b.student_id

left join class c on c.class_id=b.class_id;

LINEID     学号      姓名 语文 数学 英语 班级

---------- ----------- ------ ------ ------ ------ ------

1          20231501001 小明 80     90     50     101

2          20231501002 小红 90     68     58     102

3          20231501003 小刚 85     100    99     103

4          20231501004 小丽 95     97     98     201

5          20231501005 小花 88     96     72     202

6          20231501006 小张 82     96     82     301

7          20231501007 小刘 71     72     71     302

8          20231501008 小马 78     93     78     401

9          20231501009 小王 63     86     77     501

10         20231501010 小李 54     94     75     601

      1. left join指定学生ID查询

SQL> SELECT a.student_id as "学号",a.name as "姓名",b.chinese_score as "语文",b.math_core as "数学",b.engline_score as "英语",b.class_id as "班级" FROM student a

left join  score b ON a.student_id = b.student_id

left join class c on c.class_id=b.class_id where a.student_id='20231501009';

LINEID     学号      姓名 语文 数学 英语 班级

---------- ----------- ------ ------ ------ ------ ------

1          20231501009 小王 63     86     77     501

SQL> SELECT a.student_id as "学号",a.name as "姓名",b.chinese_score as "语文",b.math_core as "数学",b.engline_score as "英语",b.class_id as "班级" FROM student a

left join  score b ON a.student_id = b.student_id

left join class c on c.class_id=b.class_id where a.name='小丽';

LINEID     学号      姓名 语文 数学 英语 班级

---------- ----------- ------ ------ ------ ------ ------

1          20231501004 小丽 95     97     98     201

      1. left join关联查询

SQL> SELECT a.student_id,a.name,a.age,c.grade,c.name FROM student a

left join  score b ON a.student_id = b.student_id

left join class c on c.class_id=b.class_id;

LINEID     student_id  name   age grade     name 

---------- ----------- ------ --- --------- ------

1          20231501001 小明 6   一年级 一班

2          20231501002 小红 7   一年级 二班

3          20231501003 小刚 6   一年级 三班

4          20231501004 小丽 8   二年级 一班

5          20231501005 小花 6   二年级 二班

6          20231501006 小张 9   三年级 一班

7          20231501007 小刘 6   三年级 二班

8          20231501008 小马 7   四年级 一班

9          20231501009 小王 7   五年级 一班

10         20231501010 小李 8   六年级 一班

      1. 语文分数总和

SQL>  select sum(b.chinese_score) as total_score from score b left join student a on a.student_id=b.student_id;

行号     TOTAL_SCORE

---------- -----------

1          786

      1. 查询有多少学号

SQL> select count(id) from student;

+-----------+

| count(id) |

+-----------+

|        10 |

+-----------+

1 row in set (0.00 sec)

      1. 对列求和

SQL> select sum(chinese_score)  from score;

行号     SUM(CHINESE_SCORE)

---------- ------------------

1          786

      1. 对列求平均

SQL>  select AVG(chinese_score) from score;

行号     AVG(CHINESE_SCORE)

---------- ------------------

1          78.6

      1. 求某列最大值

--求某列最小值

SQL> select MAX(chinese_score),MIN(math_core) from score;

行号     MAX(CHINESE_SCORE) MIN(MATH_CORE)

---------- ------------------ --------------

1          95                 68

      1. 分组每科平均成绩

SQL> select AVG(chinese_score),AVG(math_core),AVG(ENGLINE_SCORE) from score;

行号     AVG(CHINESE_SCORE) AVG(MATH_CORE) AVG(ENGLINE_SCORE)

---------- ------------------ -------------- ------------------

1          78.6               89.2           76

SQL> select round(AVG(chinese_score),2) as 语文平均分 from score;

行号     语文平均分

---------- ---------------

1          78.6

      1. 横向求和

SQL>  select a.student_id,a.name,chinese_score+math_core+engline_score as total_score from score b

left join student a on a.student_id=b.student_id;

LINEID     student_id  name   total_score

---------- ----------- ------ -----------

1          20231501001 小明 220

2          20231501002 小红 216

3          20231501003 小刚 284

4          20231501004 小丽 290

5          20231501005 小花 256

6          20231501006 小张 260

7          20231501007 小刘 214

8          20231501008 小马 249

9          20231501009 小王 226

10         20231501010 小李 223

      1. 等值转换

SQL> select name as "姓名",(case sex when 0 then '女' else '男' end) as "性别" from student;

LINEID     姓名 性别

---------- ------ ------

1          小明 男

2          小红 女

3          小刚 男

4          小丽 女

5          小花 女

6          小张 女

7          小刘 男

8          小马 男

9          小王 女

10         小李 女

SQL> select student_id,name as "姓名",(case sex when '0' then '女' when '1' then '男' else '其他' end) as "性别" from student;

LINEID     student_id  姓名 性别

---------- ----------- ------ ------

1          20231501001 小明 男

2          20231501002 小红 女

3          20231501003 小刚 男

4          20231501004 小丽 女

5          20231501005 小花 女

6          20231501006 小张 女

7          20231501007 小刘 男

8          20231501008 小马 男

9          20231501009 小王 女

10         20231501010 小李 女

      1. 查询成绩等级

SQL> select student_id as "学号",(case when chinese_score > 90 then '优' when chinese_score >= 80 then '良' when chinese_score >= 60 then '及格' else '不及格' end) as "语文等级" from score;

LINEID     学号      语文等级

---------- ----------- ------------

1          20231501001

2          20231501002

3          20231501003

4          20231501004

5          20231501005

6          20231501006

7          20231501007 及格

8          20231501008 及格

9          20231501009 及格

10         20231501010 不及格

SQL> SELECT a.student_id as "学号",a.name as "姓名",(case when b.chinese_score > 90 then '优' when b.chinese_score >= 80 then '良' when b.chinese_score >= 60 then '及格' else '不及格' end) as "语文等级" from student a

left join  score b ON a.student_id = b.student_id;

LINEID     学号      姓名 语文等级

---------- ----------- ------ ------------

1          20231501001 小明 良

2          20231501002 小红 良

3          20231501003 小刚 良

4          20231501004 小丽 优

5          20231501005 小花 良

6          20231501006 小张 良

7          20231501007 小刘 及格

8          20231501008 小马 及格

9          20231501009 小王 及格

10         20231501010 小李 不及格

SQL> SELECT a.student_id as "学号",a.name as "姓名",b.chinese_score,(case when b.chinese_score > 90 then '优' when b.chinese_score >= 80 then '良' when b.chinese_score >= 60 then '及格' else '不及格' end) as "语文等级"  from student a

left join  score b ON a.student_id = b.student_id where b.chinese_score >='80' and  b.chinese_score <='90';

LINEID     学号      姓名 chinese_score 语文等级

---------- ----------- ------ ------------- ------------

1          20231501001 小明 80            良

2          20231501002 小红 90            良

3          20231501003 小刚 85            良

4          20231501005 小花 88            良

5          20231501006 小张 82            良

      1. 多表关联查询

SQL> SELECT a.student_id,a.name,b.chinese_score,b.math_core,b.engline_score,b.class_id FROM student a

left join  score b ON a.student_id = b.student_id

left join class c on c.class_id=b.class_id where b.chinese_score>=60 and b.math_core >=60 and b.engline_score >=60;

LINEID     student_id  name   chinese_score math_core engline_score class_id

---------- ----------- ------ ------------- --------- ------------- --------

1          20231501003 小刚 85            100       99            103

2          20231501004 小丽 95            97        98            201

3          20231501005 小花 88            96        72            202

4          20231501006 小张 82            96        82            301

5          20231501007 小刘 71            72        71            302

6          20231501008 小马 78            93        78            401

7          20231501009 小王 63            86        77            501

select student_id,name,chinese_score,math_core,engline_score from

(SELECT a.student_id,a.name,b.chinese_score,b.math_core,b.engline_score,b.class_id FROM student a

left join  score b ON a.student_id = b.student_id

left join class c on c.class_id=b.class_id where b.chinese_score>=60 and b.math_core >=60 and b.engline_score >=60)

as year2000 where  chinese_score >=80 and math_core >=80 and engline_score >=80  ;

LINEID     student_id  name   chinese_score math_core engline_score

---------- ----------- ------ ------------- --------- -------------

1          20231501003 小刚 85            100       99

2          20231501004 小丽 95            97        98

3          20231501006 小张 82            96        82

SELECT a.student_id,a.name,b.chinese_score,b.math_core,b.engline_score,b.class_id FROM student a

left join  score b ON a.student_id = b.student_id

left join class c on c.class_id=b.class_id where b.chinese_score>=80 and b.math_core >=80 and b.engline_score >=80;

LINEID     student_id  name   chinese_score math_core engline_score class_id

---------- ----------- ------ ------------- --------- ------------- --------

1          20231501003 小刚 85            100       99            103

2          20231501004 小丽 95            97        98            201

3          20231501006 小张 82            96        82            301

你可能感兴趣的:(数据库,学习,sql)