SQL语言基础

SQL语言基础

1. 数据库语言概述

SQL(Structured Query Language) 1974年由Boyce和Chamberlin提出,是在关系数据库中使用最普便的语言。

数据定义语言 DDL

数据操作语言 DML

2. SQL概述

SQL标准:ANSI SQL , SQL-92 , SQL-99

SQL 特点:综合统一、 高度非过程化、面向集合的操作方式、两种使用方式(自含式、嵌入式)、语言简洁、易学易用

SQL核心功能动词

  • 数据查询 SELECT

  • 数据定义 CREATE DROP ALTER

  • 数据操纵 INSERT UPDATE DELETE

  • 数据控制 GRANT REVORK

SQL支持三级模式结构

View 视图 对应 外模式
Base Table 基本表 对应 模式
Sored File 存储文件 对应 内模式

SQL基本组成

  1. 数据定义语言 DDL
    提供定义关系模式和视图、删除关系和视图、修改关系模式的命令

  2. 交互式数据操纵语言 DML
    提供查询、插入、修改和删除的命令

  3. 事务控制
    提供定义事务开始和结束的命令

  4. 嵌入式SQL 和 动态 SQL

  5. 完整性约束
    定义数据库中的数据必须符合完整性约束,破坏完整性的更新将被禁止

  6. 权限管理
    说明对关系和视图的访问权限

    4. 数据库定义

SQL数据类型

类型 说明
char(n) 固定长度字符串,表示n个字符的固定长度的字符串
varchar(n) 可变长度字符串,表示最多可以有n个字符的字符串
int 整型
smallint 短整型
numeric(p,d) 定点数p为整数位,n为小数位
real 浮点型
double precision 双精度浮点型
float(n) n为浮点型
boolean 布尔型
date 日期型
time 时间型
### 创建表
语句格式:
1
2
3
CREATE TABLE <表名> (<列名><数据类型>[列级完整性约束条件]
[,<列名><数据类型>[列级完整性约束条件]] ···
[,<表级完整性约束条件>]);

列级完整性约束条件有 NULL(空)和 UNIQUE (取值唯一)
表级完整性约束条件主要有 PRIMARY KEY(<列名>) (主键定义)
FOREIGN KEY(<列名>) REFERENCES <表名>(<列名>) (外键定义)
当定义主键时,主键列的 NOT NULL UNIQUE 列级完整性约束可以省略

修改表

语句格式:

1
2
3
4
5
ALTER TABLE <表名> 
[ADD <新列名><数据类型>[列级完整性约束条件]] # 新增列
[DROP <完整性约束名>] # 删除列
[MODIFY <列名><数据类型>] # 修改列的类型
[ADD CONSTRAINT <完整性约束名> <完整性约束>] # 增加约束

如定义表后,设置<字段名>为主键的语句如下:

1
2
ALTER TABLE <表名>
ADD CONSTRAINT pk_<字段名> PRIMARY KEY(<字段名>)

定义表后,设置<字段名>为外键的语句如下:

1
2
ALTER TABLE <表名>
ADD CONSTERAINT FK_<字段名> FOREIGN KEY(<字段名>) REFERENCES <参照表名>(参照字段)

删除表

语句格式:

1
DROP TABLE <表名>

创建索引

  • 索引的作用:
    数据库的索引类似书籍中的目录,利用索引在查询数据时无需扫描全表,就可以找到需要的信息。数据库的索引是表中一列或者若干列的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单
    索引通过事先排序,在查找时可以应用2分法等高效算法缩短查询时间

    1. 通过创建唯一索引,可以保证数据记录的唯一性
    2. 大大加快数据检索速度
    3. 加速表与表之间的连接,在实现数据参照完整性中非常有意义
    4. 在使用GROUP BYORDER BY子句进行检索数据时,可以显著减少查询中分组和排序的时间
    5. 使用索引可以在检索数据的过程中使用优化隐藏器,提高系统性能
  • 语句格式:

    1
    2
    CREATE [UNIQUE][CLUSTER] INDEX <索引名> 
    ON <表名>(<列名>[<次序>][,<列名>[<次序>]]···)

    参数说明:

    • 次序 :可选 ASC (升序)或DSC(降序) ,默认值为ASC
    • UNIQUE : 表明此索引是唯一索引,即每个索引值只对应唯一一条数据记录
    • CLUSTER : 表明要建立的索引是聚簇索引,表中索引项的顺序与物理记录的顺序一致。

      删除索引

      语句格式:
      1
      DROP INDEX <索引名>

视图

视图的作用

视图是从一个或多个基本表中导出的表,其结构和数据是建立在对表的查询基础上,和真实的表一样,视图也包括几个被定义的数据列和多个数据行,单本质上,这些数据均来自与其所引用的表,因此,视图不是真实存在的基本表,而是一个虚拟表。使用视图有以下优点和作用:

  1. 可以使视图集中数据,简化和定制不同用户对数据库的不同数据要求
  2. 可以屏蔽数据复杂性,用户不必了解数据库的结构,就可以方便的使用和管理数据,简化数据权限管理和重新组织数据以便输出到其他应用程序中。
  3. 视图可以使用户只关心他感兴趣的某些特定数据和他们所负责的特定任务,那些无用或不需要的数据则不在视图中显示
  4. 视图大大简化了用户对数据的操作
  5. 视图可以让不同用户以不同的方式看到不同或相同的数据
  6. 在某些情况下,由于表中的数据量太大,因此在表的设计中时常将表进行水平或者垂直分割,但表的结构的变化会对应用程序产生不良的影响,视图可以屏蔽这种不良影响
  7. 视图提供了一个简单而有效的安全机制

    视图创建

    语句格式:
    1
    2
    3
    CREATE VIEW <视图名>(<列表名>)
    AS SELECT <查询子句>
    [WITH CHECK OPTION];

注意:

  1. 查询子句可以是任意复杂的SELECT 子句,但是通常不允许有ORDER BYDISTINCT 短语
  2. WITH CHECK OPTION 表示对视图进行UPDATE INSTER DELETE操作时保证操作行满足视图定义中的条件表达式
  3. 组成视图的属性列名或者全部指定,或者全部省略,如果省略属性列名,则隐含该视图,由SELECT子查询目标列的主属性组成

    视图的删除

    语句格式:
    1
    DROP VIEW <视图名>

视图查询

视图的查询操作与基本表的查询操作完全一直

语句格式:

1
2
3
SELECT <字段名> 
FROM <视图名>
WHERE <条件表达式>

视图更新

SQL对视图的更新必须遵循以下规则:

  1. 从多个基本表通过连接操作导出的视图不允许更新
  2. 对使用了分组,集函数操作的视图不允许更新
  3. 视图是从单个基本表通过投影,选取操作导出的则允许进行更新操作

WITH子句

WITH子句提供一个定义临时视图的方式,该定义只对WITH子句出现的那一条查询有效

数据操作

SQL的数据操作功能包括查询SELECT、插入INSTER、删除DELETE和修改UPDATE四条语句

SELECT 基本结构

语句格式:

1
2
3
4
5
SELECT  [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>]···
FROM <表名或视图名>[,<表名或视图名>]···
[ WHERE <条件表达式> ]
[ GROUP BY <列名1> [HAVING<条件表达式>] ]
[ ORDER BY <列名2> [ASC|DESC] ··· ]

说明:
SQL查询中子句顺序为SELECT , FROM , WHERE , GROUP BY , HAVINGORDER BY。其中,SELECTFROM 是必需的,HAVING必须搭配GROUP BY子句使用

SQ查询子句 对应关系代数运算
SELECT 投影
FROM 笛卡尔积
WHERE 关系谓词

WHERE 子句中的条件表达式中可以使用的运算符

运算符 含义
集合成员运算符 IN 在集合中
集合成员运算符 NOT IN 不在集合中
字符串匹配运算符 LIKE 与_%进行单个、多个字符的匹配
空值比较运算符 IS NULL 是否为空
空值比较运算符 IS NOT NULL 是否不为空
算术运算符 > ,>= , < , <= ,= ,!= 大于,大于等于,小于,小于等于 ,等于,不等于
逻辑运算符 AND
OR
NOT

简单查询

找出关系中满足特定条件的元组
语句形式:

1
2
3
SELECT <字段名1>,<字段名2> ,····
FROM <表名>
WHERE <条件表达式>

连接查询

涉及两个或两个以上表查询,称为连接查询
语句形式:

1
2
3
SELECT <a表属性1>,<b表属性2> ····
FROM <a表>,<b表>
WHERE <连接条件> AND <连接后筛选条件>

子查询

子查询也称嵌套查询,嵌套查询是指SELECT - FROM - WHERE 查询块可以嵌入另一个查询块中
例1 结果作为子查询:

1
2
3
4
5
SELECT <字段名1>,<字段名2> 
FROM <表名1>
WHERE <字段名3> in (
SELECT <表2字段1> FROM <表名2> WHERE <条件表达式>
)

例2 结果作为临时表:

1
2
3
4
5
6
7
SELECT <字段名1>,<字段名2>  
FROM (
SELECT <字段名1>,<字段名2>,<字段名3>
FROM <表名>
WHERE <条件表达式>
) AS a
WHERE <条件表达式>

聚集函数

一个集合为输入,返回单个值得函数称为聚集函数。SQL提供5个预定义得集函数:平均值AVG,最小值MIN ,最大值 MAX ,求和 SUM 以及计数 COUNT

集函数的功能

集函数名 功能
COUNT([DISTINCT|ALL] *) 统计元组个数
COUNT([DISTINCT|ALL] <列名>) 统计一列中值的个数
SUM([DISTINCT|ALL] <列名>) 计算一列中值的总和,列需为数值列
AVG([DISTINCT|ALL] <列名>) 计算一列中值的平均值
MAX([DISTINCT|ALL] <列名>) 求一列中的最大值
MIN( [DISTINCT | ALL] <列名>) 求一列中的最小值

使用ANYALL谓词必须同时使用比较运算符,其含义集等价转换关系如下图,用集函数实现的子查询通常较直接使用ALLANY高效

![ANY、ALL谓词含义及等价的转换关系](C:\Users\hajnxg\Desktop\微信图片_20190513201328 (2).jpg)

分组查询

1. GROUP BY 子句

在WHERE 子句后加上GROUP BY 子句可以对元组进行分组,GROUP BY 后面跟随着一个分组属性里列表。SELECT子句使用的聚集操作符仅作用在每个分组上。

语句格式:

1
2
3
4
SELECT <字段名1>,<字段名2>,<字段名3>,<字段名4>
FROM <表名1>
WHERE <条件表达式>
GROUP BY <字段名1>,<字段名2>

2. HAVING 子句

在需要对GROUP BY 加上某种限制时,可以在其后跟随一个HAVING子句。

语句格式示例:

1
2
3
4
5
SELECT <字段名1>,<字段名2>,<字段名3>,AVG(<字段名4>)
FROM <表名1>
WHERE <条件表达式>
GROUP BY <字段名1>,<字段名2>
HAVING COUNT(<字段名4>) > 2

注意:

  • 空值在任何聚集操作中被忽略(注意是忽略,不是0),它对求和、求平均值、计数都有影响 。 如COUNT(*)统计的是关系中元组的个数,单COUNT(A)统计的是A列不为NULL的元组个数
  • NULL值又可以在分组属性中看作一个一般的值,如SELECT A,AVG(B) FROM R GROUP BY A中,当A的属性为空时,就会统计A=NULL中所有元组中B均值

更名操作

通过AS子句,可以对关系和属性重新命名

语句格式:

1
OLD_name AS NEW_name

AS子句既可以出现在SELECT 子句中,也可以出现在FROM子句中.

字符串操作

对于字符串进行的最常见的操作是使用LIKE操作符的模式匹配,使用两个特殊的字符来描述模式:%匹配任意字符串;_匹配任意一个字符。模式是大小写敏感的。

语句格式(示例):

1
2
3
SELECT <字段名> 
FROM <表名>
WHERE <字段名> LIKE "%zhangsan%"

_ _匹配只含两个字符的字符串;_ _ %匹配至少包含两个字符的字符串

SQL中允许使用escape关键词来定义转义符。

集合操作

关系代数中可以使用交、并、差(补)来组合关系,在SQL中也提供相应的操作,单查询的结果必须具有相同的属性和类型列表

1. UNION 并

对两条语句的查询结果取并集(会自动去重,如需保留重复,需使用 UNION ALL

语句格式(示例):

1
2
3
(SELECT <字段名列表> FROM <表名> WHERE <条件表达式1>)
UNION
(SELECT <字段名列表> FROM <表名> WHERE <条件表达式2>)

2. INTERSECT 交

对两条查询语句的结果集取交集

语句格式(示例):

1
2
3
(SELECT <字段名列表> FROM <表名> WHERE <条件表达式1>)
INTERSECT
(SELECT <字段名列表> FROM <表名> WHERE <条件表达式1>)

3. EXCEPT 差(补)

对两条语句的结果集取差集

语句格式(示例):

1
2
3
(SELECT <字段名列表> FROM <表名> WHERE <条件表达式1>)
EXCEPT
(SELECT <字段名列表> FROM <表名> WHERE <条件表达式2>)

SQL中的授权

主键约束 PRIMARY KEY

1. 完整性约束

完整性约束条件的作用对象有关系,元组,列三种,分为六类,如图

完整性约束条件

2. 完整性控制

完整性控制应具有三个方面的功能:定义、检测、处理

检查是否违背完整性约束的时机有两种,若在一条语句执行完毕后立即检查称为立即执行约束;若检查需要延迟到整个事务执行完成后没再执行称为延迟执行约束

数据库中最重要的约束时声明一个或一组属性形成的关系的键。键的约束实在SQL的CREATE TABLE命令中声明。

在关系系统中,最重要的完整性约束条件是:实体完整性和参照完整性

3.实体完整性

在关系中只能有一个主键。声明主键有两种方法:

  • PRIMARY KEY 保留字加在属性类型之后
  • 在属性列表中引入一个新元素,该元素包含关键字 PRIMARY KEY和用圆括号括起的形成该键的属性或者属性组列表

语句格式(示例1):

1
2
3
4
5
6
7
8
CREATE TABLE <表名>
(
<字段名1> <数据类型1>,
<字段名2> <数据类型2>,
<字段名3> <数据类型3>,
<字段名4> <数据类型4>,
PRIMARY KEY(<字段名1>)
);

语句格式(示例2):

1
2
3
4
5
6
7
CREATE TABLE <表名>
(
<字段名1> <数据类型1> PRIMARY KEY,
<字段名2> <数据类型2>,
<字段名3> <数据类型3>,
<字段名4> <数据类型4>
);

外键约束 FOREIGN KEY

外键约束对应参照完整性

语句格式:

1
2
FOREIGN KEY <属性名> REFERENCES <表名>(<属性名>)
[ON DELETE [ CASCADE | SET NULL]]

​ 参照完整性通过FOREIGN KEY 定义哪些列为外码,REGERENCR 指明外码对应哪个表的主码.ON DELETE CASCADE 指明,被参照关系删除时,同时删除参照关系中的元组。SET NULL则表示当被参照关系被删除是,将参照关系设置为空值

属性值上的约束

属性值上的约束可以通过NOT NULLUNIQUECHECK设置,其中:

  • NOT NULL : 在SQL 中,null是所有域的成员,也是每个默认属性的合法值。但是,根据用户的要求有些属性不允许取NULL值,此时可以使用NOT NULL 进行约束。
  • UNIQUE : 唯一标识数据库表中的每条记录
  • CHECK 子句可以可用于保证属性值满足指定的条件

全局约束

全局约束是指一些较为复杂的完整性约束,这些约束涉及多个属性间的联系或者多个关系间的联系。有基于元组的检查子句和断言两种方式。

  • 基于元组的检查子句

    这种约束时对单个关系的元组值加以约束,定义方法为在定义关系的任何地方加上关键字 CHECK 和约束条件。

  • 基于断言的语法格式

    语句格式:

    1
    CREATE ASSERTION <断言名> CHECK(<条件>)

授权与销权 GRANT & REVOKE

1.授权语句

语句格式:

1
GRANT <权限>[,<权限>]...[ON <对象类型> <对象名>] TO <用户>[,<用户>]...[WITH GRANT OPTION]

不同类型的操作对象有不同的操作权限,常见操作权限如下表:

对象 对象类型 操作权限
属性列 TABLE SELECT INSERT UPDATE DELETE ALL PRIVILEGES
视图 TABLE SELECT INSERTUPDATEDELETEALL PRIVILEGES`
基本表 TABLE SELECT ,INSERT, UPDATE ,DELECT ,ALTER ,INDEX ,ALL PRIVILEGES
数据库 DATABASE CREATETAB 建立表的权限 可由DBA授予普通用户

2.销权语句

语句格式:

1
2
REVOKE <权限>[,<权限>...][ON <对象类型> <对象名>]
FROM <用户>[,<用户>]

创建与删除触发器

触发器基础

触发器是指一类由事件驱动的特殊过程,有以下特点:

  • 当声明的事件发生时,触发器被激活,事件可以时对某个特定关系的插入INSERT 删除DELETE 或者 更新 UPDATE
  • 触发器被事件激活后,不是立即执行,而是先测试触发条件,若条件不成立,则不不执行
  • 如果触发器声明的条件满足,则与该触发器相连的动作有DBMS执行,动作可以阻止事件发生,可以撤销事件

触发器为数据库对象,当创建一个触发器时必须指定:

  • 触发器名称
  • 定义触发器的表
  • 触发条件
  • 触发动作

触发器可以引用数据库以外的对象,但只能在当前数据库中创建触发器,不能在临时表上或系统表上创建触发器,但触发器可引用临时表

触发动作实际时一系列SQL语句,可以有两种方式

  • 对被事件影响的没一行(FOR EACH ROW ) 每一元组执行触发过程,称为行级触发器
  • 对整个是按只执行一次的触发过程(FOR EACH STATEMNT) 称为语句级触发器,该方式是触发器的默认方式

创建触发器

触发器定义包括指明触发器的触发事件和触发器执行的动作两个方面

语句格式:

1
2
3
4
5
6
7
8
CREATE TRIGGER <触发器名> [{BEFORE|AFTER}] 
{ [DELETE | INSERT | UPDATE OF [列名清单]]}
ON <表名>
[REFERENCING <临时视图名>]
[WHEN <触发条件>]
BEGIN
<触发动作>
END [触发器名]

说明:

  • BEFORE : 指示DBMS在执行触发语句之前激发触发器
  • AFTER : 指示DBMS 在执行出发语句之后激发触发器
  • DELETE : 指明是DELETE 触发器 ,当一个DELETE语句从表中删除一行时 , 激发触发器
  • INSERT : 指明时INSERT 触发器,当一个INSERT语句向表中插入一行时,激发触发器
  • UPDATE : 指明是UPDATE触发器,当UPDATE子句修改由OF子句指定的列值时,激发触发器,如果忽略OF子句,每当UPDATE语句修改表的任何列值时,DBMS都将激发触发器
  • REFERENCING <临时视图名> : 指定临时视图的别名。
  • WHEN <触发条件>

更改和删除触发器

1. 更改触发器

语法格式:

1
2
3
4
5
6
7
ALERT TRIGGER <触发器名> [{BEFORE|AFTER}]
{ [DELETE | INSERT | UPDATE OF [列名清单]] }
ON <表名|视图名>
AS
BEGIN
<要执行的SQL语句>
END

2. 删除触发器

语法格式:

1
DROP TRIGGER <触发器名>[,...<触发器名>]

嵌入式SQL

SQL语言有两种使用方式,一种是在终端交互下使用,称为交互式SQL,另一种是嵌入主语言的程序中使用,称为嵌入式SQL

嵌入式SQL的实现方式

嵌入式SQL的实现,有两种方式:

  • 扩充主语言的编译程序,使之能处理SQL语句
  • 预处理方式

目前多数系统采用后一种方式

预处理方式是先使用预处理程序对源程序进行扫描,识别出SQL语句,并处理成主语言的函数调用形式;再用主语言的编译程序编译为目标程序。通常DBMS制造商提供一个SQL函数定义库,供编译时使用

存储设备上的数据库是用sql语句存取的,数据库和主语言间的信息传递是通过共享变量实现的。共享变量先由主语言程序定义,再用SQL和DECLARE语句说明,随后SQL就可以引用这些变量。共享变量就称为了SQL和主语言的接口

SQL2规定,SQL_STATE是一个特殊的共享变量,起着解释SQL语句执行情况的作用,它是一个由5个字符组成的字符数组,当一个SQL语句执行成功时,系统自动给SQL_STATE赋值全零(00000),表示未发生错误,否则其值为非全零,表示执行SQL语句时发生的各种错误情况,如“02000”,表示未找到元组。在执行一个SQL语句后,程序可以根据SQL_STATE的值转向不同的分支,以控制程序的流向。

嵌入式SQL的使用规定

  1. 区分SQL语句与主语言语句

    所有SQL语句前必须加上前缀标识EXEC SQL,SQL的结束标识根据主语言的不同有所不同

    如 PL/1和C语言的引用格式为:

    1
    EXEC SQL <sql语句>;

    COBOL语言的引用格式为:

    1
    2
    3
    EXEC SQL 
    <SQL语句>
    END-EXEC
  2. 允许嵌入的SQL语句引用主语言的程序变量(共享变量),须遵循2个规定

    • 引用时,变量前必须加冒号“:”作为变量标识,以示与数据库中的变量区别

    • 变量由主程序的语言定义,并用SQL的DECLARE语句说明,如在C语言中可用如下形式说明共享变量

      1
      2
      3
      4
      EXEC SQL BEGIN DECLARE SECTION; 
      char sno [5], name [9];
      char SQL_STATE [6];
      EXEC SQL END DECLARE SECTION;
  3. SQL集合处理方式与主语言单记录处理方式的协调

    由于SQL语句处理的是记录集合,而主语言语句一次只能处理一条记录,因此需要用游标(COURSOR)机制,把集合操作转换成单记录处理方式。

    • 定义游标

      游标是与某一查询结果相联系的符号名,游标用SQL的DECLARE语句来定义

      1
      2
      3
      EXEC SQL DECLARE <游标名> CURSOR FOR 
      <SELECT语句>
      END-EXEC
    • 打开游标 (OPEN)

      该语句执行游标定义的SELECT语句,同时游标处于活动状态。游标是一个指针,此时指向查询结果的第一行之前。OPEN语句句法如下:

      1
      EXEC SQL OPEN <游标名> END-EXEC
    • 推进游标(FETCH)

      将游标推进一行,并把游标指向的行(称为当前行)中的值取出送到共享变量中,其句法如下:

      1
      EXEC SQL FETCH FROM <游标名> INTO <变量名> END-EXEC

      变量名是由逗号分开的共享变量组成,FETCH语句常置于主语言程序的循环结构中,并借助主语言处理语句逐一处理查询结果中的一个一个元组

    • 关闭游标(CLOSE)

      关闭游标,使他不在和查询结果相联系,关闭了游标,可以再次打开,与新的查询结构相联系。语句句法如下:

      1
      EXEC SQL CLOSE <游标名> END-EXEC

嵌入式SQL的使用技术

SQL DDL 语句,只要加上前缀标识 “EXEC SQL”和结束标识“END-EXEC”,就能嵌入到主语言中使用,SQL DML语句在嵌入使用时,需要注意是否使用了游标机制

  • 不涉及游标的SQL DML语句

    由于INSERT DELETE UPDATE 语句不返回结果数据,只是对数据库进行操作,因此只要加上EXEC SQLEND-EXEC,就能嵌入在主语言程序中使用。对于SELECT语句,如果已知查询结果为单条元组时,加上前后缀后,也可直接嵌入使用,此时应在SELECT语句中再增加一个INTO子句,指出找到的值应送到相应的共享变量中去

  • 涉及游标的SQL DML语句

    1. SELECT 的使用方式

      当在SELECT语句查询结果是多个元组时,此时主语言程序无法使用,一定要用游标机制把多个元组一次一次的传送给主语言程序处理。

      具体过程如下:

      • 先用游标定义语句定义一个游标与某个SELECT语句对应
      • 游标用OPEN语句打开后,处于活动状态,此时游标指向查询结构的第一个元组之前。
      • 每执行一次FETCH语句,游标指向下一个元组,并把其值送到共享变量,供程序处理,如此重复,直至所有查询结果处理完毕
      • 最后用CLOSE语句关闭游标。关闭的游标可以重新打开,与新的查询结果关联,但在没有打开之前,不能使用。
    2. 对游标指向的元组修改或者删除

      游标处于活动状态时,可以修改或删除游标指向的元组

卷游标的使用和定义

游标在推进时只能沿查询结果中元组的顺序从头到尾一行一行的推进,并且不能返回,在使用中会带来不便。SQL2提供了卷游标(Scroll Cursor)技术解决了这个问题,在推进卷游标时可以进退自如。下面分别介绍卷游标的定义和推进。

  • 卷游标定义语法:
1
2
3
EXEC SQL DECLARE <游标名> SCROLL CURSOR FOR 
<SELECT语句>
END-EXEC

与游标定义相比,只多了一个关键字 SCROLL,卷游标的打开和关闭语句与前面一样

  • 卷游标推进语法:

$$
EXEC \ SQL \ FETCH \left{

​ \begin{array}

​ NEXT \ \

​ PRIOR \ \

​ FIRST \ \

​ LAST \ \

​ RELATIVE <整数> \

​ ABSOLUTE <整数> \

\end{array}

\right }

FROM\ <游标名>\ INTO\ <变量名>\ END-EXEC
$$

说明:

​ NEXT 表示把游标从当前位置推进一行;

​ PRIOR表示返回一行

​ FIRST表示把游标移向查询结果的第一行

​ LAST 表示把游标移向查询结果的最后一行

​ RELATIVE 表示把游标从当前位置推进整数行 如果为负数,则向后推进

​ ABSOLUTE 表示把游标移向查询结果的指定行 如果为负数,则是倒数指定行

动态SQL语句

前面提到的嵌入式SQL语句必须在源程序中完全确定,然后由预处理程序预处理和主语言编译程序编译,在实际问题中,源程序往往还不能包括用户的所有操作,用户对数据库的操作有时候在系统运行时才能确定,这时需要用到嵌入式SQL的动态技术来实现。

动态SQL技术主要由以下两个语句

  • 动态SQL预备语句

    1
    EXEC SQL PREPARE <动态sql语句名> FROM <共享变量或字符串>
  • 动态SQL执行语句

    1
    EXEC SQL EXECUTE <动态SQL语句名>

    动态SQL语句使用时,由两点可以改进

    • 当预备语句中组合而成的SQL语句只需执行一次时,那么预备语句和执行语句可以合并为一个语句:

      1
      EXEC SQL ECECUTE IMMEDIATE <共享变量或字符串>
    • 当预备语句中组合而成的SQL语句的条件值尚缺乏时,可以在执行语句中用USING短语补上:

      1
      EXEC SQL EXECUTE <动态SQL语句名> USING <共享变量>