第3章 关系数据库语言SQL

Download Report

Transcript 第3章 关系数据库语言SQL

第4章 结构化查询语言SQL
冯万利
2015/7/20
1
主要内容
※SQL概述
※SQL的数据定义
※SQL的数据查询
※数据更新
※嵌入式SQL
※Transact SQL语言概述
本章重点与难点
※ 重点
 (1)使用CREATE语句和DROP语句创建或撤消数据库、基
本表、视图。
 (2)使用SELECT语句表达式查询(联结、嵌套、存在量词
方式书写查询语句)。
 (3)使用INSERT、DELETE、UPDATE语句更新操作。
 (4)正确叙述SQL语句(定义、查询和更新)。
 (5)正确理解嵌入式SQL语句所表示的意义。
※ 难点
 (1)对SELECT查询语句的理解。
 (2)对视图更新操作的限制。
 (3)涉及游标的SQL DML的使用方式。
本章概述
※结构化查询语言SQL(Structured Query
Language)是关系数据库的标准语言,对关
系模型的发展和商用DBMS的研制起着重要的
作用。SQL语言是介乎于关系代数和元组演算
之间的一种语言。
※本章详细介绍SQL的核心部分内容:数据定义、
数据查询、数据更新和嵌入式SQL。
4.1 SQL概述
2015/7/20
5
主要内容
※SQL的产生与发展
※SQL的组成及特点
SQL的产生与发展
※1970年,美国IBM研究中心的E.F.Codd连续发表多篇论
文,提出关系模型。
※1972年,IBM公司开始研制实验型关系数据库管理系统
SYSTEM R,配制的查询语言称为SQUARE (Specifying
Queries As Relational Expression )语言,在语言中
使用了较多的数学符号。
※1974年,Boyce和Chamberlin把SQUARE修改为SEQUEL
(Structured English QueryLanguage )语言。后来
SEQUEL简称为SQL (Structured Query Language ),
即“结构式查询语言”,SQL的发音仍为“sequel”。
现在SQL已经成为一个标准 。
※SQL有两个标准:ANSI SQL和1992年通过的修改版本
SQL-92(简称SQL2)。还有一个新的标准SQL3,它扩充
了SQL2,引入了递归、触发器和对象等概念和机制。
SQL的组成及特点
※ SQL语言从功能上可以分为四部分:数据查(Data
Query)、数据操纵(Data Manipulation)、数据
定义(Data Definition)和数据控制(Data
Control)。
※ 核心SQL主要有四个部分:
 (1) 数据定义语言,即SQL DDL,用于定义SQL模式、基本
表、视图、索引等结构。
 (2) 数据操纵语言,即SQL DML。数据操纵分成数据查询和
数据更新两类。其中数据更新又分成插入、删除和修改三
种操作。
 (3) 嵌入式SQL语言的使用规定。这一部分内容涉及到SQL
语句嵌入在宿主语言程序中的规则。
 (4) 数据控制语言,即SQL DCL,这一部分包括对基本表和
视图的授权、完整性规则的描述、事务控制等内容。
SQL的核心动词
功
数据库查询
数据定义
数据操纵
数据控制
能
动
词
SELECT
CREATE,DROP
INSERT,UPDATE,DELECT
GRANT,REVOKE
※ SQL有两种使用方式:一是联机交互使用,另一种是
嵌入到某种高级语言程序设计语言中去使用。
※ SQL是一种第四代语言(4GL),用户只需提出“干
什么”,无需具体指明“怎么干”,像存取路径选择
和具体处理操作等,均有系统自动完成。
4.2 SQL的数据定义
※数据库的创建与撤销
※定义、修改与删除基本表
※建立与删除索引
※创建与删除视图
SQL的数据定义
SQL的数据定义功能包括数据库定义、表定义、视图和索引的定义。
操作对象
操作方式
创建
删除
数据库
CREATE DATABASE
DROP DATABASE
表
CREATE TABLE
DROP TABLE
索引
CREATE INDEX
DROP INDEX
视图
CREATE VIEW
DROP VIEW
修改
ALTER TABLE
SQL的数据定义(2)
※例4.1 定义一个教务管理数据库JWGL,它包
含3个表:
 学生表:S(SNO,SNAME,SEX,AGE,SDEPT)
 课程表:C(CNO,CNAME,CPNO,CCREDIT)
 学生选课表:SC(SNO,CNO,GRADE)
学生表实例与选课表实例
学生表实例
学号SNO
姓名SNAME
性别SEX
年龄AGE
所在系SDEPT
200915121
200915122
200915123
200915125
李小勇
刘晨
王洪敏
张力
M
F
F
M
20
19
18
19
CS
CS
MA
IS
选课表实例
学号SNO
课程号CNO
成绩GRADE
200915121
200915121
200915121
200915122
200915122
1
2
3
2
3
92
85
88
90
80
课程表实例
课程表实例
课程号CNO 课程名CNAME
1
2
3
4
5
6
7
数据库
数学
信息系统
操作系统
数据结构
数据处理
C语言
先修课CPNO
学分CCREDIT
5
4
2
4
3
4
2
4
1
6
7
6
数据库的创建
※ 对数据库的创建可用CREATE语句实现,句法如下:
 CREATE DATABASE <数据库名> AUTHORIZATION <用
户名>
 其中AUTHORIZATION <用户名>是指该用户获得授予创建
和使用数据库的权限。
※ 例如,下面语句定义了教务管理数据库的模式:
 CREATE DATABASE JWGL AUTHORIZATION张铭
 创建的数据库名为JWGL,拥有者为张铭。
数据库的撤销
※ 使用DROP语句撤消数据库。DROP语句的句法如下:
※ DROP DATABASE <数据库名> [CASCADE |
RESTRICT]
※ 撤消的方式有以下两种:
 CASCADE(连锁式)方式:执行DROP语句时,把数据库
及其下属的基本表、视图、索引等所有元素全部撤消。
 RESTRICT(约束式)方式:执行DROP语句时,只有当数
据库中没有任何下属元素时,才能撤消数据库,否则拒绝
执行DROP语句。
※ 例如,要撤消数据库JWGL及其下属所有的元素,可
用下列语句实现:
 DROP DATABASE JWGL CASCADE
基本表的定义、修改与删除
数据类型
※一个属性选用哪种数据类型要根据实际情况来
决定,一般要从两个方面来考虑,
 一是取值范围,
 二是要做哪些运算。
数据类型
数据类型
CHAR(n)
VARCHAR(n)
INT
SMALLINT
NUMERIC(p,d)
REAL
DOUBLE PRECISION
FLOAT(n)
DATE
TIME
含
义
度为n的定长字符串
最大长度为n的变长字符串
长整数(也可以写作INTEGER)
短整数
定点数,由P位数字(不包括符号、小数点)组成,
小数后面有d位数字
取决于机器精度的浮点数
取决于机器精度的双精度浮点数
浮点数,精度至少为n位数字
日期,包含年、月、日,格式为YYYY-MM-DD
时间,包含一日的时、分、秒,格式为
HH:MM:SS
不同的RDBMS中支持的数据类型不完全相同
定义基本表
※ 定义基本表,就是创建基本表的结构。其一般格式为:
CREATE TABLE <表名>
(<列名> <数据类型> [列级完整性约束条件]
[,<列名> <数据类型> [列级完整性约束条
件]]
……
[,<表级完整性约束性条件>]);
※ 建表的同时通常还可以定义与该表有关的完整性约束
条件,这些完整性约束条件被存入系统的数据字典中,
当用户操作表中数据时由RDBMS自动检查该操作是
否违背这些完整性约束条件。
例:建立学生表
CREATE TABLE S
(SNO CHAR(9) PRIMARY KEY, /* 列级完整性约束条件,
SNO是主码 */
SNAME CHAR(20) UNIQUE, /* SNAME取唯一值 */
SEX CHAR(1),
AGE SMALLINT,
SDEPT CHAR(20)
);
※ 系统执行上面的CREATE TABLE语句后,就在数据
库中建立一个新的空的“学生”表S,并将有关“学
生”表的定义及有关约束条件存放在数据字典中。
例:建立学生选课表
CREATE TABLE SC
(SNO CHAR(9),
CNO CHAR(4),
GRADE SMALLINT,
PRIMARY KEY(SNO,CNO),
/* 主码由两个属性构成,必须作为表级完整性进行定义 */
FOREIGN KEY(SNO) REFERENCES S(SNO),
/* 表级完整性约束条件,SNO是外码,被参照表是S */
FOREIGN KEY(CNO) REFERENCES C(CNO)
/* 表级完整性约束条件,CNO是外码,被参照表是C */
);
修改基本表
※ SQL语言用ALTER TABLE语句修改基本结构表,格式为:
ALTER TABLE <表名>
[ADD <新列名> <数据类型> [完整性约束]]
[DROP <完整性约束名>]
[ALTER COLUMN <列名> <数据类型>];
※ 其中<表名>是要修改的基本表。
 ADD子句用于增加新列和新的完整性约束条件;
 DROP子句用于删除指定的完整性约束条件;
 ALTER COLUMN子句用于修改原有的列定义。包括修改列名和
数据类型。
※ 例如,向S表增加“入学时间”列,其数据类型为日期型。
 ALTER TABLE S ADD S_ENTRANCE DATE;
 不论基本表中原来是否已有数据,新增加的列一律为空值。
删除基本表
※ 用DROP TABLE语句删除基本表。格式为:
※ DROP TABLE <表名> [RESTRICT | CASCADE];
 若选择RESTRICT:则该表的删除是有限制条件的。欲删除
的基本表不能被其他表的约束所引用(如CHECK,
FOREIGN KEY等约束),不能有视图,不能有触发器
(trigger),不能有存储过程或函数等。如果存在这些依
赖该表的对象,则此表不能被删除。
 若选择CASCADE:则该表的删除没有限制条件。在删除基
本表的同时,相关的依赖对象,例如视图,都将被一起删
除。
 缺省情况是RESTRICT。
※ 例4.8 删除S表。
DROP TABLE S CASCADE;
建立索引
※ 建立索引使用CREATE INDEX语句,格式为:
CREATE [UNIQUE][CLUSTER] INDEX <索引名>
ON <表名>(<列名>[<次序>][,<列名>[<次序>]]…);
 其中,<表名>是要建索引的基本表的名字。索引可以建立在该表
的一列或多列上,各列名之间用逗号分隔。每个<列名>后面还可
以用<次序>指定索引值的排列次序,可选ASC(升序)或DESC
(降序),缺省值为ASC。
 UNIQUE表明此索引的每一个索引值只对应唯一的数据记录。
CLUSTER表示要建立的索引是聚簇索引。所谓聚簇索引是指索
引项的顺序与表中记录的物理顺序一致的索引组织。
※ 例: CREATE CLUSTER INDEX STUSNAME ON S(SNAME);
将会在S表的SNAME(姓名)列上建立一个聚簇索引,而且S表
中的记录将按照SNAME值的升序存放。
删除索引
※ 索引一经建立,就由系统使用和维护它,不需用户
干预。建立索引是为了减少查询操作的时间,但如
果数据增删改频繁,系统会花费许多时间来维护索
引,从而降低了查询效率。这时,可以删除一些不
必要的索引。
※ 删除索引使用DROP INDEX语句,其一般格式为
DROP INDEX <索引名>;
※ 例: 删除S表的STUSNAME索引。
DROP INDEX STUSNAME;
※ 删除索引时,系统会同时从数据字典中删去有关该
索引的描述。
视图
※视图是从一个或几个基本表(或视图)导出的
表。它与基本表不同,是一个虚表。数据库中
只存放视图的定义,而不存放视图对应的数据,
这些数据仍存放在原来的基本表中。
建立视图
※ 用CREATE VIEW命令建立视图,格式为:
CREATE VIEW <视图名> [(<列名>[,<列名>]…)]AS
<子查询>[WITH CHECK OPTION];
※ 其中,子查询可以是任意复杂的SELECT语句,但通
常不允许含有ORDER BY子句和DISTINCT短语。
※ WITH CHECK OPTION表示对视图进行UPDATE,
INSERT和DELETE操作时要保证更新、插入或删除
的行满足视图定义中的谓词条件(即子查询中的条件
表达式)。
视图中的字段
组成视图的属性列名或者全部省略或者全部指定,如果省略了视图的
各个属性列名,则隐含该视图由子查询中SELECT子句目标列中的诸字段
组成。但在下列三种情况下必须明确指定组成视图的所有列名:
 某个目标列不是单纯的属性名,而是聚集函数或列表达式;
 多表连接时选出了几个同名列作为视图的字段;
 需要在视图中为某个列启用新的名字。
例: 建立信息系学生的视图,并要求进行修改和插入操作时仍需保证
该视图只有信息系的学生。
CREATE VIEW IS_S1 AS
加上了WITH CHECK OPTION子
SELECT SNO,SNAME,AGE
句,以后对该视图进行插入、修改
和删除操作时,RDBMS会自动加
FROM S
上SDEPT=’IS’的条件。
WHERE SDEPT=’IS’
WITH CHECK OPTION;
视图
※ 若一个视图是从单个基本表导出的,并且只是去掉了基本表的某
※
※
※
※
些行和某些列,但保留了主码,我们称这类视图为行列子集视图。
视图不仅可以建立在单个基本表上,也可以建立在多个基本表上。
例:建立信息系选修了l号课程的学生的视图。
CREATEVIEWIS_S2(SNO,SNAME,GRADE)AS
SELECTS.SNO,SNAME,GRADE
FROMS,SC
WHERESDEPT=’IS’ANDS.SNO=SC.SNOAND
SC.CNO=’1’;
由于视图IS_S2的属性列中包含了S表与SC表的同名列SNO,所
以必须在视图名后面明确说明视图的各个属性列名。
视图不仅可以建立在一个或多个基本表上,也可以建立在一个或
多个已定义好的视图上,或建立在基本表与视图上。
删除视图
※ 该语句的一般格式为:
DROP VIEW <视图名> [CASCADE];
视图删除后,视图的定义将从数据字典中被删除。如果该视图上还导
出了其他视图,则使用CASCADE级联删除语句,就可以把该视图和由它
导出的所有视图一起删除。
基本表删除后,由该基本表导出的所有视图(定义)没有被删除,但
均已无法使用了。删除这些视图(定义)需要使用DROP VIEW语句。
例:删除视图BT_S:
DROP VIEW BT_S;
删除视图IS_S1:
DROP VIEW IS_S1;
4.3 SQL的数据查询
2015/7/20
31
主要内容
※SELECT语句格式
※单表查询
※聚集函数
※数据分组
※多表查询
※集合操作
SELECT语句格式
※ SELECT—FROM—WHERE句型
在关系代数中最常用的式子是下列表达式:
πA1,…,An(σF(R1×…×Rm))
这里R1、…、Rm为关系,F是公式,A1、…、An为属性。
针对上述表达式,SQL为此设计了SELECT—FROM—
WHERE句型:
SELECT A1,…,An
FROM R1,…,Rm
WHERE F
这个句型是从关系代数表达式演变来的,但WHERE子
句中的条件表达式F要比关系代数中公式更灵活。
SELECT语句格式
※SELECT语句完整的句法如下:
SELECT 目标表的列名或列表达式序列
FROM 基本表名和(或)视图序列
[ WHERE 行条件表达式 ]
[ GROUP BY 列名序列
[ HAVING 组条件表达式 ]]
[ ORDER BY 列名[ ASC|DESC ],… ]
主语句SELECT-FROM-WHERE的含义是:
根据WHERE子句的条件表达式,从FROM子句指定的基本表
或视图中找出满足条件的元组,再按SELECT子句中的目标列表达
式,选出元组中的属性值形成结果表。
SELECT语句格式
整个语句的执行过程如下:
(1) 读取FROM子句中基本表、视图的数据,执行
笛卡尔积操作。
(2) 选取满足WHERE子句中给出的条件表达式的
元组。
(3) 按GROUP子句中指定列的值分组,同时提取满
足HAVING子句中组条件表达式的那些组。
(4) 按SELECT子句中给出的列名或列表达式求值
输出。
(5) ORDER子句对输出的目标表进行排序,按附加
说明ASC升序排列,或按DESC降序排列。
单表查询
⑴ 查询指定列
※ 在很多情况下,用户只对表中的一部分属性列感兴趣,
这时可以通过在SELECT子句的<目标列表达式>中指
定要查询的属性列。
※ 例:查询全体学生的学号与姓名。
SELECT SNO,SNAME FROM S;
※ 该语句的执行过程可以是这样的:从S表中取出一个
元组,再取出该元组在属性SNO和SNAME上的值,
形成一个新的元组作为输出。对S表中的所有元组做
相同的处理,最后形成一个结果关系作为输出。
查询全部列
※将表中的所有属性列都选出来,可以有两种方
法。一种方法就是在SELECT关键字后面列出
所有列名;另一种方法是如果列的显示顺序与
其在基表中的顺序相同,也可以简单地将<目
标列表达式>指定为“*”。
※例:查询全体学生的详细记录。
SELECT * FROM S;
等价于:
SELECT SNO,SNAME,SEX,AGE,SDEPT
FROM S;
选择表中的若干元组
※ ⑴ 消除取值重复的行
两个本来并不完全相同的元组,投影到指定的某
些列上后,可能变成相同的行了,可以用DISTINCT
取消它们。
※ 例:查询选修了课程的学生学号。
SELECT SNO FROM SC;
※ 该查询结果里包含了许多重复的行。如果想去掉结果
表中的重复行,必须指定DISTINCT关键词:
SELECT DISTINCT SNO FROM SC;
⑵ 查询满足条件的元组
※ 查询满足指定条件的元组可以通过WHERE子句实现。
※ 例:查询计算机科学系全体学生的名单。
SELECT SNAME FROM S
WHERE SDEPT=’CS’;
查询条件
比较
确定范围
确定集合
字符匹配
空值
多重条件(逻辑运算)
谓
词
=,>,<,>=,<=,!=,<>,!>,!<,NOT+上述运算符
BETWEEN AND,NOT BETWEEN AND
IN,NOT IN
LIKE,NOT LIKE
IS NULL,IS NOT NULL
AND,OR,NOT
范围查询
※ 谓词BETWEEN…AND…和NOT
BETWEEN…AND…可以用来查找属性值在(或不在)
指定范围内的元组,其中BETWEEN后是范围的下限
(即低值),AND后是范围的上限(即高值)。
※ 例:查询年龄在20~23岁(包括20岁和23岁)之间的
学生的姓名、系别和年龄。
SELECT SNAME,SDEPT,AGE FROM S
WHERE AGE BETWEEN 20 AND 23;
※ 与BETWEEN…AND…相对的谓词是NOT
BETWEEN…AND…。
※ 例:查询年龄不在20~23岁之间的学生姓名、系别和
年龄。
SELECT SNAME,SDEPT,AGE FROM S
WHERE AGE NOT BETWEEN 20 AND 23;
确定集合
※ 谓词IN可以用来查找属性值属于指定集合的元组。
※ 例:查询计算机科学系(CS)、数学系(MA)和信
息系(IS)学生的姓名和性别。
SELECT SNAME,SEX FROM S
WHERE SDEPT IN(’CS’,’MA’,’IS’);
※ 与IN相对的谓词是NOT IN,用于查找属性值不属于
指定集合的元组。
※ 例:查询既不是计算机科学系、数学系,也不是信息
系的学生的姓名和性别。
SELECT SNAME,SEX FROM S
WHERE SDEPT NOT IN(’CS’,’MA’,’IS’);
字符匹配谓词
※ LIKE可以用来进行字符串的匹配。其一般语法格式
如下:
※ [NOT] LIKE ‘<匹配串>’[ESCAPE‘<换码字符
>’]
 其含义是查找指定的属性列值与<匹配串>相匹配的元组。
 <匹配串>可以是一个完整的字符串,也可以含有通配符%
和_。
 %(百分号)代表任意长度(长度可以为0)的字符串。例
如a%b表示以a开头,以b结尾的任意长度的字符串。如acb,
addgb,ab等都满足该匹配串。
 _(下划线)代表任意单个字符。例如a_b表示以a开头,以
b结尾的长度为3的任意字符串。如acb,afb等都满足该匹
配串。
单表查询举例
例:查询学号为200915121的学生的详细情况。
SELECT *
FROM S
WHERE SNO LIKE ’200915121’;
等价于:
SELECT *
FROM S
WHERE SNO=’200915121’;
如果LIKE后面的匹配串中不含通配符,则可以用=(等于)运算符取代
LIKE谓词,用!=或<>(不等于)运算符取代NOT LIKE谓词。
例: 查询所有姓刘的学生的姓名、学号和性别。
SELECT SNAME,SNO,SEX
FROM S
WHERE SNAME LIKE ’刘%’;
单表查询举例
涉及空值的查询例
例:某些学生选修课程后没有参加考试,所以有选课记录,但没有考试
成绩。查询缺少成绩的学生的学号和相应的课程号。
SELECT SNO,CNO
FROM SC
WHERE GRADE IS NULL;
/* 分数GRADE是空值 */
 多重条件查询
可用逻辑运算符AND和OR来联结多个查询条件。AND的优先级高于
OR,但可以用括号改变优先级。
例:查询计算机科学系年龄在20岁以下的学生姓名。
SELECT SNAME
FROM S
WHERE SDEPT=’CS’ AND AGE<20;

ORDER BY子句
※ 用户可以用ORDER BY子句对查询结果按照一个或多个
属性列的升序(ASC)或降序(DESC)排列,缺省值为升
序。
例:查询选修了3号课程的学生的学号及其成绩,查询结
果按分数的降序排列。
SELECT SNO,GRADE
FROM SC
WHERE CNO=’3’
ORDER BY GRADE DESC;
对于空值,若按升序排列,含空值的元组将在最后显示。
若按降序排列,空值的元组将在最前面显示。
聚集函数 (1)
聚合函数是涉及整个关系的另一类运算操作。通过聚合函数,可以把
某一列中的值形成单个值。SQL不仅允许聚合属性上的值,而且可以按照某
个准则将关系中的元组分组。
※ COUNT(*) 计算元组的个数。
※ COUNT(列名) 对一列中的值计算个数。
※ SUM(列名) 求某一列值的总和(此列的值必须是数值型)。
※ AVG(列名) 求某一列值的平均值(此列的值必须是数值型)。
※ MAX(列名) 求某一列值的最大值。
※ MIN(列名) 求某一列值的最小值。
如果指定在列名前面指明DISTINCT短语,则表示在计算时要取消指
定列中的重复值。如果不指定DISTINCT短语或指定ALL短语(ALL为
缺省值),则表示不取消重复值。
聚集函数 (2)
例:查询选修了课程的学生人数。
SELECT COUNT(DISTINCT SNO)
FROM SC;
学生每选修一门课,在SC中都有一条相应的记录。一个学生要选修多
门课程,为避免重复计算学生人数,必须在COUNT函数中用DISTINCT短
语。
例: 计算选修l号课程的学生平均成绩。
SELECT AVG(GRADE)
FROM SC
WHERE CNO=’1’;
例:查询选修l号课程的学生最高分数。
SELECT MAX(GRADE)
FROM SC WHERE CNO=’1’;
数据分组
对查询结果分组的目的是为了细化聚集函数的作用对象。如果未对查
询结果分组,聚集函数将作用于整个查询结果。在实际应用中,经常需要
将查询结果进行分组,然后再对每个分组进行统计。
GROUP BY子句将查询结果按某一列或多列的值分组,值相等的为一
组,分组后聚集函数将作用于每一个组,即每一组都有一个函数值。
例: 求各个课程号及相应的选课人数。
SELECT CNO,COUNT(SNO)
FROM SC
GROUP BY CNO;
该语句对查询结果按CNO的值分组,所有具有相同CNO值的元组为一
组,然后对每一组作用聚集函数COUNT计算,以求得该组的学生人数。
如果分组后还要求按一定的条件对这些组进行筛选,最终只输出满足
指定条件的组,则可以使用HAVING短语指定筛选条件。
多表查询 (1)
在多表查询中,如果要引用不同关系中的同名属性,则需要在属性名
前加关系名,即用“关系名.属性名”的形式表示,以便区分。
※ 连接查询
⑴ 等值与非等值连接查询
连接查询的WHERE子句中用来连接两个表的条件称为连接条件或连接
谓词,其一般格式为:
[<表名1>.] <列名1> <比较运算符> [<表名2>.]<列名2>
其中比较运算符主要有:=、>、<、>=、<=、!=(或<>)等。
此外连接谓词还可以使用下面形式:
[<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2>
AND [<表名3>.]<列名3>
多表查询 (2)
例:查询每个学生及其选修课程的情况。
学生情况存放在S表中,学生选课情况存放在SC表中,所以本查询实
际上涉及S与SC两个表。这两个表之间的联系是通过公共属性SNO实现的。
SELECT S.*,SC.*
FROM S,SC
WHERE S.SNO=SC.SNO; /* 将S与SC中同一学生的元组连接起来
*/
执行步骤:首先在表S中找到第一个元组,然后从头开始扫描SC表,
逐一查找与S第一个元组的SNO相等的SC元组,找到后就将S中的第一个
元组与该元组拼接起来,形成结果表中一个元组。SC全部查找完后,再找
S中第二个元组,然后再从头开始扫描SC,逐一查找满足连接条件的元组,
找到后就将S中的第二个元组与该元组拼接起来,再形成结果表中一个元组。
重复上述操作,直到S中的全部元组都处理完毕为止。这就是循环嵌套算法
的基本思想 。
(2) 自身连接
※ 连接操作不仅可以在两个表之间进行,也可以是一个
表与其自己进行连接,称为表的自身连接。
※ 例:查询每一门课的间接先修课(即先修课的先修
课)。
※ 在C表中,只有每门课的直接先修课信息,而没有先
修课的先修课。要得到这个信息,必须先对一门课找
到其先修课,再按此先修课的课程号,查找它的先修
课程。这就将C表与其自身连接。为此,要为C表取
两个别名,一个是FIRST,另一个是SECOND。完成
该查询的SQL语句为
SELECT FIRST.CNO,SECOND.CPNO
FROM C FIRST,C SECOND
WHERE FIRST.CPNO=SECOND.CNO;
(3) 外连接
有时想以S表为主体列出每个学生的基本情况及其选课
情况。若某个学生没有选课,仍把舍弃的表S元组保存在
结果关系中,而在SC表的属性上填空值(NULL),这时
就需要使用外连接。
例4.56 查询每个学生及其选修课程的情况。 :
SELECT
S.SNO,SNAME,SEX,AGE,SDEPT,CNO,GRAGE
FROM S LEFT OUT JOIN SC
ON(S.SNO=SC.SNO);
/* 也可以使用USING来去掉结果中的重复值:
FROM S LEFT OUT JOIN SC USING(SNO); */
(4) 复合条件连接
※ WHERE子句中可以有多个连接条件,称为复合条件
连接。
※ 例: 查询选修2号课程且成绩在90分以上的所有学生
的学号和姓名。
SELECT S.SNO,SNAME
FROM S,SC
WHERE S.SNO=SC.SNO AND SC.CNO=’2’
AND SC.GRADE>90;
※ 该查询的一种优化(高效)的执行过程是先从SC中
挑选出CNO=’2’并且GRADE>90的元组形成一个
中间关系,再和S中满足连接条件的元组进行连接得
到最终的结果关系。
嵌套查询
※ 在SQL语言中,一个SELECT─FROM─WHERE语句
称为一个查询块。将一个查询块嵌套在另一个查询块
的WHERE子句或HAVING短语的条件中的查询称为
嵌套查询(nested query)。
※ ⑴ 带有IN谓词的子查询
※ 例:查询与“刘晨”在同一个系学习的学生。
※ 先分步来完成此查询,然后再构造嵌套查询。
① 确定“刘晨”所在系名
SELECT SDEPT
FROM S
WHERE SNAME=’刘晨’;
结果为:CS
② 查找所有在CS系学习的学生。
SELECT SNO,SNAME,SDEPT
FROM S
WHERE SDEPT=’CS’;
嵌套查询
将第一步查询嵌人到第二步查询的条件中,构造嵌套查询如下:
SELECT SNO,SNAME,SDEPT
FROM S
WHERE SDEPT IN
(SELECT SDEPT
FROM S
WHERE SNAME=’刘晨’
);
本例中,子查询的查询条件不依赖于父查询,称为不相关子查询。
一种求解方法是由里向外处理,即先执行子查询,子查询的结果
用于建立其父查询的查找条件。
嵌套查询
例: 查询选修了课程名为“信息系统”的学生学号和姓名。
本查询涉及学号、姓名和课程名3个属性。学号和姓名存放在S表中,
课程名存放在C表中,但S与C两个表之间没有直接联系,必须通过SC表建
立它们二者之间的联系。所以本查询实际上涉及3个关系。
SELECT SNO,SNAME /* 外层在S关系中取出SNO和SNAME */
FROM SWHERE SNO IN
(SELECT SNO
/* 在SC关系中找出选修了3号课程的学生学号 */
FROM SC
WHERE CNO IN
(SELECT CNO
/* 在C关系中找出“信息系统”的课
FROM C
程号,结果为3号 */
WHERE CNAME=’信息系统’ ) );
嵌套查询
本查询同样可以用连接查询实现:
SELECT S.SNO,SNAME
FROM S,SC,C
WHERE S.SNO=SC.SNO AND SC.CNO=C.CNO
AND C.CNAME=’信息系统’;
说明: 有些嵌套查询可以用连接运算替代,有些是不能替代的。
如果子查询的查询条件依赖于父查询,这类子查询称为相关子查询
(Correlated Subquery)。
例: 找出每个学生超过他选修课程平均成绩的课程号。
SELECT SNO,CNO
FROM SC X
WHERE GRADE>=(SELECT AVG(GRADE) /* 某学生的平均成绩 */
FROM SC Y
WHERE Y.SNO=X.SNO);
嵌套查询
例:查询其他系中比计算机科学系某一学生年龄小的学生姓名和年龄。
SELECT SNAME,AGE
FROM S
注意这是父查询
WHERE AGE<
块中的条件
ANY(SELECT AGE
FROM S
WHERE SDEPT=’CS’) AND Sdept<>’CS’;
RDBMS执行此查询时,首先处理子查询,找出CS系中所有学
生的年龄,构成一个集合(20,19)。然后处理父查询,找所有不
是CS系且年龄小于20或l9的学生。
多表查询
子查询的结果是一个关系,可用于这个关系的SQL运算符有:IN,ALL,ANY。
多表查询
例 对基本表S、SC、C的数据进行检索。
(1) 检索至少有一门成绩超过学生S4一门成绩的学生学号。
SELECT S#
FROM SC
WHERE GRADE>SOME(SELECT GRADE
FROM SC
WHERE S#=‘S4’)
多表查询
(2) 检索平均成绩最高的学生学号。
SELECT S#
为什么要这个语句?
FROM SC
GROP BY S#
HAVING AVG(GRADE)>=ALL(SELECT AVG(GRADE)
FROM SC
GROUP BY S#);
例:使用运算符IN,求选修了C4课程的学生的学号和姓名。
SELECT S#,SNAME
Ⅰ FROM S
WHERE S# IN (SELECT S#
Ⅱ FROM SC
WHERE C# IN(SELECT C#
Ⅲ FROM C
WHERE C#=‘C4’)))
执行子查询嵌套时由内层向外层逐层处理,外层利用内层的结果。
多表查询
※ 一些带EXISTS或NOT EXISTS谓词的子查询不能被
其他形式的子查询等价替换,但所有带IN谓词、比较
运算符、ANY和ALL谓词的子查询都能用带EXISTS
谓词的子查询等价替换。
※ 例:查询与“刘晨”在同一个系学习的学生。
SELECT SNO,SNAME,SDEPT
FROM S S1
WHERE EXISTS
(SELECT *
FROM S S2
WHERE S2.SDEPT=S1.SDEPT AND
S2.SNAME=’刘晨’);
多表查询
例: 查询选修了全部课程的学生姓名。
SQL中没有全称量词(FOR ALL)。可将题目的意思转换成等价的形
式:查询这样的学生,没有一门课程是他不选修的。其SQL语句为:
SELECT SNAME
FROM S
WHERE NOT EXISTS
(SELECT *
FROM C
WHERE NOT EXlSTS
(SELECT *
FROM SC
WHERE SNO=S.SNO AND CNO=C.CNO));
从而用EXIST/NOT EXIST来实现带全称量词的查询。
多表查询
例: 查询至少选修了学生200915122选修的全部课程的学生号码。
本查询可以用逻辑蕴涵来表达:查询学号为x的学生,对所有的课程y,
只要200915122学生选修了课程y,则x也选修了y。
也可以将语义表达为:不存在这样的课程y,学生200915122选修了y,
而学生x没有选,用SQL语言表示如下:
SELECT DISTINCT SNO
FROM SC SCX
WHERE NOT EXISTS (SELECT *
FROM SC SCY
WHERE SCY.SNO=’200915122’
AND NOT EXISTS
(SELECT *
FROM SC SCZ
WHERE SCZ.SNO=SCX.SNO AND
SCZ.CNO=SCY.CNO));
集合操作 (1)
SELECT语句的查询结果是元组的集合,所以多个SELECT语句的结
果可进行集合操作。
例: 查询计算机科学系的学生及年龄不大于19岁的学生。
SELECT *
FROM S
WHERE SDEPT=’CS’
UNION
SELECT *
FROM S
WHERE AGE<=19;
本查询实际上是求计算机科学系的所有学生与年龄不大于19岁的学生
的并集。使UNION将多个查询结果合并起来时,系统会自动去掉重复元组。
如果要保留重复元组则需要换为UNION ALL操作符。
集合操作 (2)
例: 查询既选修了1号课程又选修了2号课程的全体学生。就是查询选
修1号课程的学生集合与选修2号课程的学生集合的交集。
SELECT SNO
FROM SC
WHERE CNO=’l’
INTERSECT
SELECT SNO
FROM SC
WHERE CNO=’2’;
本例也可以表示为
SELECT SNO
FROM SC
WHERE CNO=’1’ AND SNO IN
(SELECT SNO FROM SC
WHERE CNO=’2’);
4.4数据更新
2015/7/20
67
主要内容
※数据插入
※数据删除
※数据修改
※对视图的更新操作
数据插入
※ 插入元组
插入元组的INSERT语句的格式为
INSERT INTO <表名> [(<属性列1>[,(属性列2>…)]
VALUES(<常量1> [,<常量2>]…);
其功能是将新元组插入指定表中,其中新元组的属性列1的值为常量
1,属性列2的值为常量2,…。INTO子句中没有出现的属性列,新元组
在这些列上将取空值。
但必须注意的是,在表定义时说明了NOT NULL的属性列不能取空
值,否则会出错。
如果INTO子句中没有指明任何属性列名,则新插入的元组必须在每
个属性列上均有值。
数据插入
例:将一个新学生元组(学号:200915128;姓名:陈冬;性别:
M;所在系:IS;年龄:l8)插入到S表中。
INSERT INTO
S(SNO,SNAME,SEX,SDEPT,AGE)
VALUES(’200915128’,’陈冬’,’M’,’IS’,l8);
在INTO子句中指出了表名S,指出了新增加的元组在哪些属性上
要赋值,属性的顺序可以与CREATE TABLE中的顺序不一样,
VALUES子句对新元组的各属性赋值,字符串常数要用单引号(英
文符号)括起来。
例: 将学生张成民的信息插入到S表中。
INSERT INTO S
VALUES(’200915126’,’张成民’,’M’,18,’CS’);
数据插入
例: 插入一条选课记录(‘200915128’,’1’)。
INSERT INTO SC(SNO,CNO)
VALUES(’200915128’,’1’);
RDBMS将在新插入记录的GRADE列上自动地赋空值。
或者:
INSERTINTO SC
VALUES(’200915128’,’1’,NULL);
因为没有指出SC的属性名,在GRADE列上要明确给
出空值。
数据插入
※ 插入子查询结果
子查询不仅可以嵌套在SELECT语句中,用以构造父查询的条件,
也可以嵌套在INSERT语句中,用以生成要插入的批量数据。
插入子查询结果的INSERT语句的格式为
lNSERT INTO <表名>
[(<属性列1> [,<属性列2>…)]
子查询;
例: 对每一个系,求学生的平均年龄,并把结果存入数据库。首
先在数据库中建立一个新表,其中一列存放系名,另一列存放相应
的学生平均年龄。
CREATE TABLE DEPT_AGE
(SDEPT CHAR(15)
AVG_AGE SMALLINT
);
数据插入
然后对S表按系分组求平均年龄,再把系名和平均年
龄存入新表中。
INSERT INTO
DEPT_AGE(SDEPT,AVG_AGE)
SELECT SDEPT,AVG(AGE)
FROM SGROUP BY SDEPT;
数据删除
※ SQL的删除操作是指从基本表中删除元组,其句法如下:
DELETE FROM 基本表名
[WHERE 条件表达式]
其语义是从基本表中删除满足条件表达式的元组。删除语句实际上
是“SELECT * FROM基本表名[WHERE条件表达式]”和DELETE操
作的结合,每找到一个元组,就把它删去。应该注意,DELETE语句
只能从一个基本表中删除元组。WHERE子句中条件可以嵌套,也可以
是来自几个基本表的复合条件。
※三种删除方式
 删除某一个元组的值
 删除多个元组的值
 带子查询的删除语句
数据删除
例: 删除学号为200915128的学生记录。
DELETE
删除某一个元组的值
FROM S
WHERE SNO=’200915128’;
例: 删除所有的学生选课记录。
DELETE
删除多元组的值
FROM SC;
这条DELETE语句将使SC成为空表,
它删
除了SC的所有元组。
例: 删除计算机科学系所有学生的选课记录。
DELETE
FROM SC
WHERE ’CS’=
(SELECT SDEPT
FROM S
WHERE S.SNO=SC.SNO);
带子查询的删除语句
数据修改
修改操作又称为更新操作,其语句的一般格式为
UPDATE <表名> SET <列名>=<表达式>
[,<列名>=<表达式>]…
[WHERE <条件>];
其功能是修改指定表中满足WHERE子句条件的元组。
其中SET子句给出<表达式>的值用于取代相应的属性列
值。如果省略WHERE子句,则表示要修改表中的所有
元组。
 修改某一个元组的值;
 修改多个元组的值;
 带子查询的修改语句。
数据修改
例: 将学生200915121的年龄改为22岁。
修改一个元组的值
UPDATE S
SET AGE=22
WHERE SNO=’200915121’;
例: 将所有学生的年龄增加l岁。
修改多个元组的值
UPDATE S
SET AGE=AGE+1;
例:将计算机科学系全体学生的成绩置零。
UPDATE SC
带子查询的修改语句
SET GRADE=0
WHERE ’CS’=
(SELETE SDEPT
FROM S
WHERE S.SNO=SC.SNO);
对视图的更新操作
视图定义后,就可以像对待基本表一样对视图进行查询(SELECT)
操作。但对视图中的元组进行更新操作就不一样了。这是由于视图是
不实际存储数据的虚表,对视图的更新最终要转换为对基本表的更新。
对于视图元组的更新操作(INSERT、DELETE、UPDATA),有
以下三条规则:
⑴ 如果一个视图是从多个基本表使用联接操作导出的,那么不允
许对这个视图执行更新操作。
⑵ 如果在导出视图的过程中,使用了分组和聚集函数操作,也不
允许对这个视图执行更新操作。
⑶ 行列子集视图是可以执行更新操作的。
在SQL2中,允许更新的视图在定义时,必须加上“WITH
CHECK OPTION”短语。
对视图的更新操作
例: 将信息系学生视图IS_S中学号为200915122的学生姓名改为“刘
辰”。
UPDATE IS_S SET SNAME=’刘辰’
WHERE SNO=’200915122’;
转换后的更新语句为:
UPDATE S SET SNAME=’刘辰’
WHERE SNO=’200915122’ AND SDEPT=’IS’;
例: 向信息系学生视图IS_S中插入一个新的学生记录,其中学号为
200915129,姓名为赵新,年龄为20岁。
INSERT INTO IS_S VALUES(’200915129’,’赵新’,20);
转换为对基本表的更新:
INSERTINTO S(SNO,SNAME,AGE,SDEPT)
VALUES(’200915129’,’赵新’,20,’IS’);
这里系统自动将系名’IS’放入VALUES子句中。
对视图的更新操作
例: 删除信息系学生视图IS_S中学号为200915129的记录。
DELETE
FROM IS_S
WHERE SNO=’200915129’;
转换为对基本表的更新:
DELETE
FROM S
WHERE SNO=’200915129’ AND SDEPT=’IS’;
在关系数据库中,有些视图是不可以更新的,其原因是这些视
图的更新不能唯一地有意义地转换成对相应基本表的更新。看下面
例题。
对视图的更新操作
例: 将学生的学号及他的平均成绩定义为一个视图。
CREAT VIEW S_G(SNO,GAVG) AS
SELECT SNO,AVG(GRADE)
FROM SCGROUP BY SNO;
如果想把视图S_G中学号为200915121的学生的平均成绩改成90分,
SQL语句如下:
UPDATE S_G
SET GAVG=90
WHERE SNO=’200915121’;
但这个对视图的更新是无法转换成对基本表SC的更新的,因为系统无
法修改各科成 绩,以使平均成绩成为90。所以S_G视图是不可更新的。
一般地,行列子集视图是可更新的。除行列子集视图外,还有些视图
理论上是可更新的,但它们的确切特征还是尚待研究的课题。还有些视图
从理论上就是不可更新的。
4.5嵌入式SQL
2015/7/20
82
主要内容
※ 嵌入式SQL
※动态SQL简介
嵌入式SQL简介 (1)
SQL语言有两种使用方式:一种是在终端交互方式下使用,称为
交互式SQL;另一种是嵌入在高级语言的程序中使用,称为嵌入式SQL,
而这些高级语言可以是C、Visual Basic、DELPHI、Power Builder等,
称为宿主语言。
嵌入式SQL的实现,有两种处理方式:一种是扩充宿主语言的编
译程序,使之能处理SQL语句;另一种是采用预处理方式。目前多数系
统采用后一种方式。
嵌入式SQL简介 (2)
SQL函数定义库
宿主语言十嵌入式SQL

预处理程序

宿主语言十函数调用

宿主语言编译程序

目标程序
源程序处理过程
预处理方式是先用预处理程序对源程序进行扫描,识别出SQL语句,
并处理成宿主语言的函数调用形式;然后再用宿主语言的编译程序译
成目标程序。
嵌入式SQL简介 (3)
※ 在宿主语言的程序中使用SQL语句有以下规定:
⑴ 为区分SQL语句与宿主语言语句,在所有的SQL语句前必须加上前
缀标识“EXEC SQL”,并以“END_EXEC”作为语句结束标志。
格式如下:
EXEC SQL <SQL语句> END_EXEC
结束标志在不同的宿主语言中是不同的,在Power Builder和C语言程
序中规定结束标志不用END_EXEC,而使用分号“;”。
⑵ 允许嵌入的SQL语句引用宿主语言的程序变量(称为共享变量),
并规定在引用这些变量时必须在这些变量前加冒号“:”作为前缀标识,以
表示与数据库中变量有区别,而且这些变量由宿主语言的程序定义,并由
SQL的BEGIN DECLARE SECTION与END DECLARE SECTION语句之
间说明。而主语言不能引用数据库中的字段变量。
嵌入式SQL简介 (4)
⑶ 游标。SQL语言与主语言具有不同的数据处理方式。SQL是面
向集合的,一条SQL语句原则上可以产生或处理多条记录。而宿主语
言是面向记录的,一次只能处理一条记录。为此引入游标来协调这两
种不同的处理方式。通过游标机制,把集合操作转换成单记录处理方
式。 与游标有关的语句有下列四个:
① 定义游标语句(DECLARE)。游标是与某一查询结果相联系的
符号名,用DECLARE语句定义。这是一个说明语句,定义中的
SELECT语句并不立即执行,句法如下:
EXEC SQL DECLARE <游标名> CURSOR FOR
<SELECT语句>
END_EXEC
② 打开游标语句(OPEN)。打开游标语句使游标处于活动状态。
与游标相应的查询语句被执行。游标指向查询结果的第一个记录之前。
句法如下:
EXEC SQL OPEN <游标名> END_EXEC
嵌入式SQL简介 (5)
③ 推进游标语句(FETCH)。
此时游标推进一个记录,并把游标指向的记录(称为当前行)中
的值取出,送到INTO子句后相应的主变量中。句法如下:
EXEC SQL FETCH FROM <游标名> INTO <变量表>
END EXEC
FETCH语句常用于宿主语言程序的循环结构中,并借助宿主语言
的处理语句逐一处理查询结果中的一个个元组。
④ 关闭游标语句(CLOSE)。
关闭游标,使它不再和查询结果相联系。关闭了的游标,可以再
次打开,与新的查询结果相联系。句法如下:
EXEC SQL CLOSE <游标名> END_EXEC
在游标处于活动状态时,可以修改和删除游标指向的元组。
嵌入式SQL简介 (6)
 嵌入式SQL的使用技术
在嵌入式SQL中,SQL的数据定义DDL与控制语句DCL都不需要使用
游标。它们是嵌入式SQL中最简单的一类语句,不需要返回数据结果,也
不需要使用变量。只要给语句加上前缀EXEC SQL和语句结束符
END_EXEC就可以嵌入。
⑴ 不涉及游标的SQL语句不需要使用游标的语句。
① 查询结果为单记录的SELECT语句这类语句不需要使用游标,因为
查询结果只有一个,只需要用INTO子句指定存放查询结果的主变量。
例4.86 根据学生号码查询学生信息。假设已经把要查询的学生的学号
赋给了主变量GIVENSNO。
EXEC SQL SELECT SNO,SNAME,SEX,AGE,SDEPT
INTO :HSNO,:HNAME,:HSEX,:HAGE,:HDEPT
FROM S
WHERE SNO=:GIVENSNO;
嵌入式SQL简介 (7)
为了表示空值,在INTO子句的主变量后面跟有指示变量,当查询得出
的某个数据项为空值时,系统会自动将相应主变量后面的指示变量置为负
值,而不再向该主变量赋值。所以当指示变量值为负值时,不管主变量为
何值,均认为主变量值为NULL。
注意:指示变量只能用于INTO子句中。
例4.87 查询某个学生选修某门课程的成绩。假设已经把将要查询的学
生的学号赋给了主变量GIVENSNO,将课程号赋给了主变量GIVENCNO。
EXEC SQL SELECT SNO,CNO,GRADE
INTO :HSNO,:HCNO,:HGRADE :GRADEID /* 指示变量
GRADEID */
FROM SC
WHERE SNO=:GIVENSNO AND CNO=:GIVENCNO;
如果GRADEID<0,则不论HGRADE为何值,均认为该学生成绩为空
值。
嵌入式SQL简介 (8)
② 非CURRENT形式的增删改语句有些增删改语句不需要使用游
标,是非CURRENT形式的。在UPDATE的SET子句和WHERE子句中
可以使用主变量,SET子句还可以使用指示变量。
例4.88 修改某个学生选修l号课程的成绩。
EXEC SQL UPDATE SC
SET GRADE=:NEWGRADE /* 修改的成绩已赋给主变量 */
WHERE SNO=:GIVENSNO /* 学号已赋给主变量GIVENSNO
*/例4.89 某个学生退学了,现要将有关他的所有选课记录删除掉。假
设该学生的姓名已赋给主变量STDNAME。 EXEC SQL DELETE
FROM SC
WHERE SNO=
(SELECT SNO
FROM SWHERE SNAME=:STDNAME);
嵌入式SQL简介 (9)
⑵ 使用游标的SQL语句有:
① 查询结果为多条记录的SELECT语句需要用游标机制,将多条记录
一次一条送主程序处理,从而把对集合的操作转换为对单个记录的处理。
说明游标。用DECLARE语句为一条SELECT语句定义游标。定义游标
仅仅是一条说明性语句,这时RDBMS并不执行SELECT语句。
打开游标。用OPEN语句将定义的游标打开。打开游标实际上是执行相
应的SELECT语句,把查询结果取到缓冲区中。这时游标处于活动状态,
指针指向查询结果集中的第一条记录。
推进游标语句。用FETCH语句把游标指针向前推进一条记录,同时将
缓冲区中的当前记录取出来送至主变量供主语言进一步处理。通过循环执
行FETCH语句逐条取出结果集中的行进行处理。
关闭游标。用CLOSE语句关闭游标,释放结果集占用的缓冲区及其他
资源。游标被关闭后,就不再和原来的查询结果集相联系。
嵌入式SQL简介 (10)
② CURRENT形式的UPDATE和DELETE语句
UPDATE语句和DELETE语句都是集合操作,如果只想修改或删除其
中某个记录,则需要用带游标的SELECT语句查出所有满足条件的记录,
从中进一步找出要修改或删除的记录,然后用CURRENT形式的UPDATE
和DELETE语句修改或删除之。即UPDATE语句和DELETE语句中要用子
句:
WHERE CURRENT OF <游标名>
来表示修改或删除的是最近一次取出的记录,即游标指针指向的记录。
注意:当游标定义中的SELECT语句带有UNION或ORDER BY子句时,
或者该SELECT语句相当于定义了一个不可更新的视图时,不能使用
CURRENT形式的UPDATE语句和DELETE语句。
动态SQL简介 (1)
动态SQL方法允许在程序运行过程中临时“组装”SQL语句。动态
SQL支持动态组装SQL语句和动态参数两种形式。
※ 使用SQL语句主变量
程序主变量包含的内容是SQL语句的内容,而不是原来保存数据的输
入或输出变量,这样的变量称为SQL语句主变量。SQL语句主变量在程序
执行期间可以设定不同的SQL语句,然后立即执行。
例4.91 创建基本表TEST。
EXEC SQL BEGIN DECLARE SECTION;
CONST CHAR * STMT=” CREATE TABLE TEST(A INT);”;
/* SQL语句主变量 */
EXEC SQL END DECLARE SECTION;
……
EXEC SQL EXECUTE IMMEDIATE :STMT; /* 执行语句 */
动态SQL简介 (2)
※
动态参数
动态参数是SQL语句中的可变元素,使用参数符号(?)表示该位置
的数据在运行时设定。动态参数的输入是通过(PREPARE)语句准备主
变量和执行(EXECUTE)时绑定数据或主变量来完成。
使用动态参数的步骤:
⑴ 声明SQL语句主变量。变量的SQL内容包含动态参数(?)。
⑵ 准备SQL语句(PREPARE)。PREPARE将分析含主变量的SQL
语句内容,建立语句中包含的动态参数的内部描述符,并用<语句名>标识
它们的整体。句法如下:
EXEC SQL PREPARE <语句名> FROM <SQL语句主变量>;
⑶ 执行准备好的语句(EXECUTE)。EXECUTE将SQL语句中分析
出的动态参数和主变量或数据常量绑定作为语句的输入或输出变量。
EXEC SQL EXECUTE <语句名> [INTO <主变量表>]
[USING <主变量或常量>];
动态SQL简介 (3)
例: 向TEST中插入元组。
EXEC SQL BEGIN DECLARE SECTION;
CONST CHAR *STMT=”INSERT INTO TEST
VALUES(?);”;
/* 声明SQL主变量 */
EXEC SQL END DECLARE SECTION;
……
EXEC SQL PREPARE MYSTMT FROM :STMT; /* 准备语句 */
……
EXEC SQL EXECUTE MYSTMT USING 100; /* 执行语句 */
EXEC SQL EXECUTE MYSTMT USING 200; /* 执行语句 */
4.6 Transact SQL语言概述
2015/7/20
97
主要内容
※ 查询分析器
※ T-SQL语言
查询分析器
※Transact SQL(简称T-SQL)语言是SQL
Server使用的SQL语言。与SQL Server通讯
的所有应用程序都是通过向服务器发出T-SQL
语句来进行通讯的。
查询分析器
SQL查询分析器提供如下功能:
(1) 用于输入T-SQL语句的自由格式文本编辑器。
(2) 在T-SQL语句中使用不同的颜色,以提高复杂语句的易读性。
(3) 对象浏览器和对象搜索工具,可以轻松查找数据库中的对象和对象
结构。
(4) 模板可用于加快创建SQL Server对象的T-SQL语句的开发速度。模
板是包含创建数据库对象所需的T-SQL语句基本结构的文件。
(5) 用于分析存储过程的交互式调试工具。
(6) 以网格或自由格式文本窗口的形式显示结果。
(7) 显示计划信息的图形关系图,用以说明内置在T-SQL语句执行计划
中的逻辑步骤。
(8) 使用索引优化向导分析T-SQL语句以及它所引用的表,以了解通过
添加其他索引是否可以提高查询的性能。
查询分析器
运行
 【开始】菜单上选择【程序】| Microsoft SQL Server
2005 |【查询分析器】命令。
 SQL Server企业管理器内。
数据定义语言
※ 数据定义语言(DDL)是指用来定义和管理数据库以及数据库中各种对象的
语句,这些语句包括CREATE、ALTER和DROP等。
※ 例: 创建教务管理数据库JWGL。
CREATE DATABASE JWGL ON
/* 数据文件的描述 */
(NAME=JWGL_data,
/* 数据库逻辑文件名 */
FILENAME=’C:\DATA\JWGL.MDF’, /* 数据库文件要保存的路径
及文件名 */
SIZE=4,
/* 初始数据库文件的大小 */
MAXSIZE=10,
/* 数据库文件的最大值
(MB)*/
FILEGROWTH=10% )
/* 数据文件的自动增长率 */
LOG ON
/* 事务日志描述 */
( NAME=JWGL_log,
/* 日志逻辑文件名 */
FILENAME=’C:\DATA\JWGL_log.mdf’, /* 日志文件要保存的路径及
文件名 */
SIZE=1,
/* 初始日志文件的大小 */
MAXSIZE=6,
/* 日志文件的最大值 */
FILEGROWTH=1
/* 增长率可以是百分比也可以是具
体值 */
);
T-SQL语言举例
※ 例:创建数据库表S(学生表)。
CREATE TABLE S
/* 下面的例子将创建
表S */
( SNO CHAR(9) NOT NULL
/* 学号字段 */
CONSTRAINT PK_SNO PRIMARY KEY CLUSTERED
/* 主键约束 */
CHECK
(SNO LIKE ’200915121[0-9][0-9]’),
/* 检查约束 */
SNAME CHAR(8) NULL,
/* 姓名字段 */
SEX CHAR(1) NULL,
/* 性别字段 */
AGE INT NULL,
/* 年龄字段 */
SDEPT VARCHAR(20) NULL
/* 系别字段 */
);
T-SQL语言举例
※ 例:创建数据库表S(学生表)和表SC(选课表)。
CREATE TABLE SC
( SNO CHAR(9) NOT NULL,
CNO CHAR(4) NOT NULL,
GRADE NUMERICAL(4,1) NULL
);
/* 学号字段 */
/* 课程编号字段 */
/* 成绩字段 */
※ 例: 修改S表,增加一个班号列。
ALTER TABLE S ADDCLASS_NO CHAR(6);
※ 例: 删除S表。
DROP TABLE S;
数据操纵语言
※ 数据操纵语言是指用来查询、添加、修改和删除数据库中数据的
语句。
※ 例: 查询选修’1’或’2’号课程的学生的学号、课程号和成绩。
SELECT SNO, CNO, GRADE
FROM SC
WHERE CNO IN (’1’,’2’);
※ 例: 通过查询求选修’1’号课程的最高分、最低分及它们之间相
差的分数。
SELECT MAX(GRADE) AS MAXGRADE, MIN(GRADE) AS
MINGRADE, MAX(GRADE)-MIN(GRADE) AS DIFF
/* 定义别
名DIFF */
FROM SC
WHERE (CNO =’1’)
举例
※ 例: 求出各位学生的平均成绩,把结果存放在新表AVGGRADE中。
CREATE TABLE AVGGRADE
/* 建立新表AVGGRADE用来存放学号和学生的平均成绩 */
(
SNO CHAR(9),AVGGR SMALLINT /* 存放平均成绩字段
*/
)
※ 下面利用子查询求出SC表中各位学生的平均成绩,把结果存放在
新表AVGGRADE中。
INSERT INTO AVGGRADE
SELECT SNO,AVG(GRADE)
FROM SCGROUP BY SNO
举例
※ 例: 创建把讲授’5’号课程的教师的工资增加100元。
※ 假设教师基本情况表的结构为
T(TNO,TN,SEX,AGE,PROF,SAL,DEPT)分别表示教师的编号,
姓名,性别,年龄,职称,工资,系别。教师授课表的结构为
TC(TNO,CNO)分别表示教师的编号,课程编号。
UPDATE T
SET SAL=SAL+100
WHERE TNO IN
(SELECT T.TNO
FROM T,TC
WHERE T.TNO=TC.TNO AND TC.CNO=’5’
/* 通过连接查询找到讲授’5’号课程的
教师编号 */
)
使用企业管理器创建表
选
择
要
新
建
表
的
数
据
库
选择新建表
使用企业管理器创建表
使用企业管理器创建表
使用企业管理器修改表结构
使用企业管理器删除表
删除数
据库zzg
中的表
student1
重要内容分析
2015/7/20
113
重要内容分析 (1)
SELECT语句是SQL的核心内容,对于该语句考生应掌
握下列内容。
1.SELECT语句的来历
在关系代数中最常用的式子是下列表达式:
πA1,…,An(σF (R1×…×Rm))
这里R1、…、Rm为关系,F是公式,A1、…、An为属性。
针对上述表达式,SQL为此设计了SELECT—FROM—
WHERE句型:
SELECT A1,…,An
FROM R1,…,Rm
WHERE F
这个句型是从关系代数表达式演变来的,但WHERE子句中的条
件表达
式F要比关系代数中公式更灵活。
重要内容分析 (2)
2. SELECT语句的语义有三种情况。
下面以学生表S(S#,SNAME,AGE,SEX)为例说明。
第一种情况:SELECT语句中未使用分组子句,也未使用聚合操作,那
么SELECT子句的语义是对查询的结果执行投影操作。例如:
SELECT S#,SNAME
FROM S
WHERE SEX=‘M’;
第二种情况:SELECT语句中未使用分组子句,但在SELECT子句中使用了聚合操作,此时
SELECT子句的语义是对查询结果执行聚合操作。例如:
SELECT COUNT(*),AVG(AGE)
FROM S
WHERE SEX='M';
该语句是求男同学的人数和平均年龄。
重要内容分析 (3)
第三种情况:SELECT语句使用了分组子句和聚合操作(有分组
子句时必有聚
合操作),此时SELECT子句的语义是对查询结果的每一分组去做聚
合操作。
例如:
SELECT AGE,COUNT(*)
FROM S
WHERE SEX='M'
GROUP BY AGE;
该语句是求男同学每一年龄的人数。
重要内容分析(4)
3.分组子句与聚合操作:
SELECT语句中使用分组子句的先决条件是要有聚合操作。但执行
聚合操
作不一定要用分组子句。譬如求男同学的人数,此时聚合值只有一个,
因此不必分
组。
但同一个聚合操作的值有多个时,必须使用分组子句。譬如求每一
年龄的学生
人数。此时聚合值有多个,与年龄有关,因此必须分组。