第三章关系数据库标准语言
SQL语言主要内容
§ 3.1 SQL概述
§ 3.2 查询语句
§ 3.3 更新语句
§ 3.4 SQL DDL
§ 3.5 SQL DCL
§ 3.6 视图
§ 3.7 嵌入式 SQL


§ 3.1 SQL概述一,SQL的发展及现状二,SQL数据库的体系结构三,SQL的功能四,SQL的形式五,SQL的特点
§ 3.1 SQL概述一,SQL的发展及现状
– 1974年,由 Boyce和 Chamberlin提出
– 1975~1979,IBM San Jose Research Lab的关系数据库管理系统原型 System R实施了这种语言
– SQL-86是第一个 SQL标准
– SQL-89,SQL-92(SQL2),SQL-99(SQL3)
– 大部分 DBMS产品都支持 SQL,成为操作数据库的标准语言二,SQL数据库的体系结构
SQL 用户
Base Table
B1
View V1 View V2
Base Table
B2
Base Table
B3
Base Table
B4
Stored File
S1
Stored File
S1
Stored File
S1
Stored File
S1
外模式模式内模式
SQL语言支持的关系数据库的三级模式结构二,SQL数据库的体系结构基本概念:
–1、用户可以用 SQL语言对视图 (View)和基本表 (Base
Table)进行查询等操作,在用户观点里,视图和表一样,
都是关系。
–2,视图 是从一个或多个基本表中导出的表,本身不存储在数据库中,只有其定义,可以将其理解为一个虚表。
–3,基本表 是本身独立存在的表,每个基本表对应一个存储文件,一个表可以带若干索引,存储文件及索引组成了关系数据库的内模式。
SQL 用户
Base Table
B1
View V1 View V2
Base Table
B2
Base Table
B3
Base Table
B4
Stored File
S1
Stored File
S1
Stored File
S1
Stored File
S1
外模式模式内模式三,SQL的功能
数据定义( DDL)
定义、删除、修改关系模式(基本表)
定义、删除视图( View)
定义、删除索引( Index)
数据操纵( DML)
数据查询
数据增、删、改
数据控制( DCL)
用户访问权限的授予、收回四,SQL的组成 (分类 )
DATABASE
TABLE
CREATE VIEW
INDEX
SQL DDL:
ALTER
DROP
SQL QUERY,SELECT … FROM …
INSERT …
SQL SQL DML,UPDATE …
DELETE …
GRANT
SQL DCL,REVOKE
AUDIT
嵌入式 SQL:
五,SQL的形式
交互式 SQL
一般 DBMS都提供联机交互工具
用户可直接键入 SQL命令对数据库进行操作
由 DBMS来进行解释
嵌入式 SQL
能将 SQL语句嵌入到高级语言(宿主语言)
使应用程序充分利用 SQL访问数据库的能力、宿主语言的过程处理能力
一般需要预编译,将嵌入的 SQL语句转化为宿主语言编译器能处理的语句六,SQL的特点
4,具有查询、操作、定义和控制四种语言一体化的特点。
它只向用户提供一种语言,但该语言具有上述多种功能,
且每种操作只需一种操作符。
1,高度非过程化的语言,用户只需提出“干什么”,至于
“怎么干”由 DBMS解决;用户只需要早查询语句中提出需要什么,DBMS即可按路径存取,并把结果返回给用户。
2,面向集合的语言,每一个 SQL的操作对象是一个或多个关系,操作的结果也是一个关系。
3.一种语法结构,两种使用方式,即可独立使用,又可嵌入到宿主语言中使用,具有自主型和宿主型两种特点。
五,SQL的特点
5,语言简洁、易学易用:核心功能只有 9个动词,语法简单,
接近英语。
SQL功能 动词数据库查询 SELECT
数据定义 CREATE,DROP,ALTER
数据操纵 INSERT,UPDATE,DELETE
数据控制 GRANT,REVOKE
(一 ) 数据类型
1、字符型,CHAR(n),VAR CHAR
2、数字型,INT,SMALLINT,REAL…
3、日期型,DATE,TIME
(二 ) 函数
1,数字函数,
ABS(X),SQRT(X),RAND(X),LOG(X),…
2,字符函数:
LENGTH(X$),LOWER(X$),UPPER(X$),
SUBSTRING(expression,start,length)…
3.分组函数:
COUNT(* ),MAX(X),MIN(X),AVG(X),
SUM(X)
(三 ) 运算符
1,句法操作符,&
2,数值操作符,+,-,*,/,…
3,逻辑操作符,
=,>,<,≤,≥,≠,IN,ANY,ALL,…
4,查询表达式操作符,UNION,…
5,其它操作符,*,(+),…
基本结构
Select A1,A2,...,An
From R1,R2,...,Rm
Where P
§ 3.2 查询语句数据查询是数据库应用的核心功能
Select Where From
A1,A2,...,An(?p(R1× R2×,..× Rm))
§ 3.2 查询语句
■ 语句格式 (P72)
SELECT [ALL|DISTINCT] [表名,]{*|列名 |表达式
[AS 新列名 ]}
[INTO,主变量 1[,:主变量 2]… ]
FROM 表名 [表别名 ],…
[WHERE 条件表达式 |子查询 ]
[GROUP BY 列名 1,…
[HAVING 分组表达式 ]]
[{UNION|INTERSECT |EXCEPT}SELECT… FROM… ]
[ORDER BY 列名 |列序号 [ASC|DESC],… ];
SELECT… FROM常用语句执行过程
SELECT… ⑤ 投影
FROM… ① TABLE→ 内存
WHERE… ② 选取元组
GROUP… ③ 分组
HAVING… ④ 选择分组
[{UNION|… } ⑥ 查徇结果的集合运算
SELECT… ] ① ~⑤
ORDER BY…… ⑦ 排序输出
A1,...,An(?p(R1×,..× Rm))
Select A1,A2,...,An
From R1,R2,...,Rm
Where P
一、单表查询
1,选择表中的列
2,选择表中的行
3,分组与组函数
4,排 序一、单表查询
1,选择表中的列例 1.求学生所在系及姓名
SELECT SD,SN
FROM S;
例 2.求学生的全部信息
SELECT S#,SN,SA,SD
FROM S;
(SELECT *)
SELECT Sname NAME,'Year of Birth:'BIRTH,
2003-Sage BIRTHDAY,
LOWER(Sdept) DEPARTMENT
FROM Student;
例 3.查全体学生的姓名、出生年份和所有系,要求用小写字母表示所有系名
SELECT Sname,'Year of Birth:',
2003-Sage,LOWER(Sdept)
FROM Student;
2,选择表中的行
1) 消除重复行,DISTINCT (缺省为 ALL)
例,求选修了课程的学生号
SELECT DISTINCT S#
FROM S;
Where 子句 —— 运算符
比较,<,<=,>,>=,=,<>,not + ~
确定范围:
Between A and B,Not Between A and B
确定集合,IN,NOT IN
字符匹配,LIKE,NOT LIKE
空值,IS NULL,IS NOT NULL
多重条件,AND,OR,NOT
用 WHERE子句实现复杂查询条件例,求年龄在 18~ 22 (含 18,22)之间的学生名及年龄 (或不在 18~ 22之间 )
SELECT SN,SA
FROM S
WHERE SA BETWEEN 18 AND 22;
(WHERE SA>=18 AND SA<=22);
(WHERE SA NOT BETWEEN 18 AND 22);
(WHERE SA<18 OR SA>22);
例:求计算机系年龄小于 19的姓名及年龄
SELECT SN,SA
FROM S
WHERE SD=’CS’ AND SA<19;
2) 选满足一定条件的行:
3)查询条件来自集合:
用 IN or NOT IN
例,求信息工程系、计算机系、数学系的系名、
学生名 (或不是这些系的学生 )
SELECT SD DEPT,SN NAME
FROM S
WHERE SD IN (‘IE’,‘CS’,‘MA’);
(WHERE SD=‘IE’ OR SD=‘CS’ OR SD=‘MA’)
(WHERE SD NOT IN (‘IE’,‘CS’,‘MA’);
(WHERE SD!=‘IE’ AND SD!=‘CS’ AND SD!=‘MA’)
Where 子句 —— Like
格式,
[NOT] LIKE ‘匹配串’ [ESCAPE ‘换码字符’ ]
%,表示任意长度 (≥0的任意字符
__,表示单个的任意字符
ESCAPE ‘换码字符’,
匹配串中‘换码字符’ (转义符 )之后的字 (%,__),被定义为普通字符 (不作通配符用 )
4) 字符匹配,
例:列出课程名称中带有‘ _’的课号及课名 。
Select cno,cname
From Course
Where cname LIKE ‘%\_%’ escape ‘\’
例 1,求课程名中有’数据库’的课程记录
SELECT *
FROM C
WHERE CN LIKE ‘%数据库 %’;
例 2,求倒数第三、四个汉字为 ’ 系统 ’ 的课程名
SELECT CN
FROM C
WHERE CN LIKE ‘%系统 _ _ _ _’;
例 3,求以 ‘ DATA_BASE’开头且倒数第五个字符为 ’ S’的课程名
SELECT CN
FROM C
WHERE CN LIKE
‘DATA\_BASE%S_ _ _ _’ ESCAPE’\’;
例,查缺少成绩的学生的学号和相应的课程号
SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL;
5) 涉及空值的查询,
Group By子句
–将查询结果集按某一列或多列的 值 分组,值相等的为一组,一个分组以一个元组的形式出现
–只有出现在 Group By子句中的属性,才可出现在
Select子句中例,统计各系学生的人数。
Select sdept,count(*) as stu_count
From Student
Group By sdept
3、分组与组函数组函数,
1)组函数的使用格式:
COUNT([DISTINCT|ALL] *|列名 )
SUM([DISTINCT|ALL] 列名 )
AVG([DISTINCT|ALL] 列名 )
MAX([DISTINCT|ALL] 列名 )
MIN([DISTINCT|ALL] 列名 )
2) 组函数可用于 SELECT子句中的目标列表中,或在 HAVING子句的分组表达式中用作条件。
3) 对分出的每一组用 HAVING进行筛选,
筛选条件要用到组函数。
例 1,查询各个课程号与相应的选课人数
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
例 2,查男女生人数
SELECT sex,COUNT(SNO) COUNTSNO
FROM stu
GROUP BY sex;
例 3,求选修了课程的学生人数
SELECT COUNT(DISTINCT S#)
FROM SC;
例 4,求选修各门课的人数及平均成绩
SELECT C#,COUNT(S#),AVG(ALL GR)
FROM SC
GROUP BY C#;
例 5,求选修课程在 5门以上且都及格的学生号及总平均分
SELECT S#,AVG(ALL GR)
FROM SC
GROUP BY S#
HAVING COUNT(C#)>5
AND MIN(GR)≥60 ;
Having 与 Where的区别
Where 决定哪些元组被选择参加运算,作用于关系中的元组
Having 决定哪些分组符合要求,作用于分组
4、排序
1) 用 ORDER BY子句对查询结果按照一个或多个列的值进行升 /降排列输出
2) 升序为 ASC;降序为 DESC
3) 空值将作为最大值排序例 1,对选修 ’ C5’课程的学生按成绩降序排列,同分数者按学号升序排列
SELECT S#,GR
FROM SC
WHERE C#=’C5’
ORDER BY GR DESC,S# ASC;
例 2,求每个学生的总分并按总分降序排列,
学号升序
SELECT S#,SUM(ALL GR)
FROM SC
GROUP BY S#
ORDER BY 2 DESC,S# ASC;
求 95级学生中选修课程在 5 门以上且都及格的学生号及总平均分,并按平均成绩排序。
A1,...,An(?p(R1×,..× Rm))
Select A1,A2,...,An
From R1,R2,...,Rm
Where P
一、单表查询
1,选择表中的列
2,选择表中的行
3,分组与组函数
4,排 序主要内容二、连接查询多表连接查询、单表连接查询、
外连接查询、复合条件连接查询,
三、嵌套查询一、单表查询返回单个值的子查询返回一组值的子查询多重子查询二、连接查询多表连接查询、单表连接查询、
外连接查询、复合条件连接查询,
* 示范表
EMP(EMPNO,ENAME,MGR,JOB,SAL,DEPTNO)
DEPT(DEPTNO,DNAME,CITY)
SALGRADE(GRADE,LOSAL,HISAL)
1、多表连接:
1) 连接条件一:
[表名 1.] 列名 1 比较运算符 [表名 2.]列名 2
2) 连接条件二:
[表名 1.]列名 1 BETWEEN [表名 2.]列名 2
AND [表名 2.]列名 3
■ 连接条件中的列名称为连接字段,其各字段应是可比的。
执行过程:
学号 课程号 学习成绩S# C# GRADE
S1 C1 A S1 C2 A
S1 C3 A S1 C5 B
S2 C1 B S2 C2 C
..,.,.
SC
学号 学生姓名 所属系名 学生年龄S# SNAME SD SA
S1 A CS 20S2 B CS 21
S3 C MA 19S4 D CI 19
S5 E MA 20..,.,.,.
S
在表 1中找到第一个元组,然后从头开始扫描表 2,查找到满足条件的元组即进行串接并存入结果表中;再继续扫描表 2,
依次类推,直到表 2末尾。再从表 1中取第二个元组,重复上述的操作,直到表 1中的元组全部处理完毕。
例题
SELECT ENAME,SAL,GRADE
FROM EMP,SALGRADE
WHERE SAL BETWEEN LOSAL AND HISAL;
SELECT S.S#,SN,CN,G
FROM S,C,SC
WHERE S.S#=SC.S# AND C.C#=SC.C#;
例 2,求每个职工的工资级别例 1,求选课情况,要求输出学号、姓名、课程名与成绩
2、单表连接,
用表别名把一个表定义为两个不同的表进行连接。
SELECT W.ENAME,W.SAL,M.ENAME,M.SAL
FROM EMP W,EMP M
WHERE W.MGR = M.EMPNO
AND W.SAL > M.SAL;
例 1,求比本部门职工工资低的部门负责人例题
SELECT FIRST.C#,THIRD.CNAME
FROM C FIRST,C SECOND,C THIRD
WHERE FIRST.PC# = SECOND.C# AND
SECOND.PC# = THIRD.C#
例 2,求每门课的间接先修课名(即先修课的先修课)
3、外连接,
在连接条件的某侧加上 (* )或 (+),表示该侧所对应的表中可形成一个各数据项均为空值的万能替代行,用来与另一侧对应的表中所有不满足条件的元组进行连接 。 外连接符 (* )或 ( +) 出现在左侧称为右外连接,出现在右侧称为左连接,两侧都出现的称为全外连接 。
SELECT DNAME,ENAME,JOB
FROM DEPT,EMP
WHERE DEPT.DEPTNO = EMP.DEPTNO(*);
例 1,求各部门名及职工名、工种,要求输出无职工的部门(职工以空值出现)
例题
SELECT DNAME,ENAME,JOB
FROM DEPT,EMP
WHERE DEPT.DEPTNO(*) = EMP.DEPTNO;
例 2,求各部门名及职工名、工种,要求输出未分配部门的职工(部门以空值出现)
例题
SELECT DNAME,ENAME,JOB
FROM DEPT,EMP
WHERE DEPT.DEPTNO(*)=EMP.DEPTNO(*);
例 3,求各部门名及职工名,工种,要求输出无职工的部门和未分配部门的职工
4、复合条件连接,
WHERE子句中除了连接条件,还有其它限制条件 。
SELECT SN,GR
FROM S,SC
WHERE S.S#=SC.S# AND SC.C#=’C6’
AND SC.GR>90;
例 1,求选修 ’ C6’课程且成绩超过 90分的学生名与成绩连接条件 限制条件三,嵌套查询
在 SELECT … FROM … WHERE语句结构的
WHERE子句中可嵌入一个 SELECT语句块
其上层 查询称为外层查询或父查询
其下层 查询称为内层查询或子查询
SQL语言允许使用多重嵌套查询
在 子查询中不允许使用 ORDER BY子句
嵌套查询的实现一般是从里到外,即先进行子查询,再把其结果用于父查询作为条件
1、返回单个值的子查询,
方法一:
SELECT SN,SA
FROM S
WHERE SD =
( SELECT SD
FROM S
WHERE SN = ‘刘力 ’ );
例 1,求与‘刘力’同一个系的学生名,年龄
1、返回单个值的子查询,
方法二:
SELECT FIRST.SN,FIRST.SA
FROM S FIRST,S SECOND
WHERE FIRST.SD = SECOND.SD
AND SECOND.SN = ‘刘力 ’ ;
例 1,求与‘刘力’同一个系的学生名,年龄
2、返回一组值的子查询,
SELECT *
FROM S
WHERE S# IN
( SELECT S#
FROM SC
WHERE C#=‘C6’
AND GR> 90 );
例 1,求选修 ‘ C6‘课程且成绩超过 90分的学生方法一:
例题
SELECT S.*
FROM S,SC
WHERE S.S#=SC.S#
AND GR> 90
AND C#=’C6’;
例 1,求选修 ‘ C6‘课程且成绩超过 90分的学生方法二( 连接查询 ):
例题方法一:
SELECT *
FROM S
WHERE SD!=’CS’
AND SA < ANY
( SELECT SA
FROM S
WHERE SD=‘CS’);
例 2,求比计算机系中某一学生年龄小的其他系的学生例题方法二:
SELECT *
FROM S
WHERE SD!=’CS’
AND SA <
( SELECT MAX(SA)
FROM S
WHERE SD=‘CS’);
例 2,求比计算机系中某一学生年龄小的其他系的学生
3、多重子查询,
例 1,求 10#部门中工种与‘ SALES’部门中任一工种相同的职工例题
SELECT ENAME,JOB,SAL
FROM EMP
WHERE DEPTNO = ‘10’
AND JOB IN
(SELECT JOB
FROM EMP
WHERE DEPTNO =
( SELECT DEPTNO
FROM DEPT
WHERE DNAME=‘SALES’));
例题
SELECT *
FROM EMP
WHERE SAL > =
(SELECT MIN(SAL)
FROM EMP
WHERE ENAME IN (‘CLARK’,‘ MILLER’))
AND SAL < =
(SELECT MAX(SAL)
FROM EMP
WHERE ENAME IN( ‘ CLARK’,‘MILLER’);
例 2,求工资介于 ‘ CLARK’与 ‘ MILLER’两个之间的职工例题
SELECT DEPTNO,ENAME,JOB,SAL
FROM EMP
WHERE JOB IN
(SELECT JOB
FROM EMP
WHERE DEPTNO IN
(SELECT DEPTNO
FROM DEPT
WHERE CITY = ’NEW YORK’));
例 3,求工种与在纽约的职工的工种相同的职工总 结连接查询多表连接查询、单表连接查询、
外连接查询、复合条件连接查询嵌套查询返回单个值的子查询返回一组值的子查询多重子查询四、带有 EXISTS的相关子查询
不相关子查询,子查询的查询条件不依赖于父查询的称为不相关子查询。
相关子查询,子查询的查询条件依赖于外层父查询的某个属性值的称为相关子查询
(Correlated Subquery),带 EXISTS的子查询就是相关子查询
EXISTS表示存在量词
带有 EXISTS的子查询不返回任何记录的数据,
只返回逻辑值 ‘ True ’ 或 ‘ False ’
例题不相关子查询:
SELECT SN
FROM S
WHERE S# IN
( SELECT S#
FROM SC
WHERE C# = ‘C1’ );
例 1,求所有选修了 ‘ C1’课程的学生名。
例题相关子查询:
SELECT SN
FROM S
WHERE EXISTS
( SELECT *
FROM SC
WHERE S.S#=SC.S#
AND C#=‘C1’ );
例 1,求所有选修了 ‘ C1’课程的学生名。
执行过程:
学号 课程号 学习成绩S# C# GRADE
S1 C1 A S1 C2 A
S1 C3 A S1 C5 B
S2 C1 B S2 C2 C
..,.,.
SC
学号 学生姓名 所属系名 学生年龄S# SNAME SD SA
S1 A CS 20S2 B CS 21
S3 C MA 19S4 D CI 19
S5 E MA 20..,.,.,.
S
先在外层查询中取 S表的第一个元组(记录),用该记录的相关的属性值(在内层 WHERE子句中给定的)处理内层查询,若外层的 WHERE子句返回 ‘ TRUE’值,则此元组送入结果的表中。然后再取下一个元组;重复上述过程直到外层表的记录全部遍历一次为止。
说明:
不关心子查询的具体内容,因此用 SELECT *
Exists + 子查询用来判断该子查询是否返回元组
当子查询的结果集非空时,Exists 为 ‘ True’
当子查询的结果集为空时,Exists 为 ‘ False’
NOT EXISTS,若子查询结果为空,返回 ‘ TRUE’值,
否则返回 ‘ FALSE’
例题
SELECT SN
FROM S
WHERE NOT EXISTS
( SELECT *
FROM C
WHERE S.S#=SC.S#
AND C#=‘C1’);
例 2,列出没有选 C1课程的学生的学号、姓名例题
SELECT SN
FROM S
WHERE NOT EXISTS
( SELECT *
FROM C
WHERE NOT EXISTS
( SELECT *
FROM SC
WHERE S.S#=SC.S#
AND C.C#=SC.C#));
例 3,查询选修了所有课程的学生的姓名这门课他没选这样的课是不存在的例题例 4,查询至少选修了 ‘ S1’所选的全部课程的学生名
P,S1选修了课程 CX Q,学生 SX选修了课程 CX
则,?CX(P→ Q)表示学生 SX选修了‘ S1’所选的全部课程
(P→ Q)==?P ∨ Q
X(P→ Q)==?(?X (?(P→ Q)))
==?(?X (?(? P ∨ Q)))
==?(?X (P ∧? Q))
即,?X(P→ Q)==?(?X (P ∧? Q))
SELECT SN
FROM S
WHERE NOT EXISTS?(?X
( SELECT *
FROM SC SCX S1选课
WHERE SCX.S#=‘S1’ P
AND NOT EXISTS ∧?
( SELECT *
FROM SC SCY
WHERE S.S#=SCY.S#
AND SCX.C#=SCY.C#)); Q
FROM语句中使用子查询 (SQL2)
在 FROM语句中使用子查询,对查询结果定义表名及列名例,求平均成绩超过 80分的学号及平均成绩
SELECT S#,AVG_G
FROM (SELECT S#,AVG(ALL G)
FROM SC
GROUP BY S# )
AS RA(S#,AVG_G)
WHERE AVG_G>80;
SELECT S#,AVG(ALL G)
FROM SC
GROUP BY S#
HAVING AVG(ALL G)>80
五,SQL的集合操作
属性个数必须一致
对应的类型必须一致
属性名无关
最终结果集采用第一个结果的属性名
缺省为自动去除重复元组
除非显式说明 ALL
Order By放在整个语句的最后
SQL的集合操作 —— 并例 1:查询计算机系的学生 或者 年龄不大于 19岁的学生,
并按年龄倒排序。
SELECT *
FROM S
WHERE SD=‘CS’
UNION
SELECT *
FROM S
WHERE AGE<=19
ORDER BY AGE DESC
SQL的集合操作 —— 交例 2:查询计算机系的学生 并且 年龄不大于 19岁的学生,
并按年龄倒排序。
(SELECT *
FROM S
WHERE SD=‘CS’)
INTERSEC
(SELECT *
FROM S
WHERE AGE<=19)
ORDER BY AGE DESC
SQL的集合操作 —— 差例 3:查询选修课程 1但没有选修课程 2的学生。
SELECT SN,SD
FROM S
WHERE S# IN
(( SELECT S#
FROM SC
WHERE C#='1‘)
EXCEPT
( SELECT S#
FROM SC
WHERE C#='2'))
§ 3.3 更新语句一、插入操作 INSERT
二、删除操作 DELETE
三、修改操作 UPDATE
一、插入操作
1、插入单个元组:
格式,INSERT INTO 表名 [(列名 1,… )]
VALUES (列值 1,… );
插入一已知元组的全部列值
插入一已知元组的部分列值
插入一已知元组的全部列值
INSERT INTO S
VALUES(‘990021’,‘陈冬 ’,18,‘CS’,‘男 ’ );
例 1,新增一个学生信息
INSERT INTO SC( S#,C#)
VALUES (‘9807121’,‘C175’);
插入一已知元组的部分列值例 2,新增一条选课记录格式,INSERT INTO 表名 [(列名 1,… )]
(子查询 );
例 1,设关系 S_G(S#,AVG_G),把平均成绩大于
80的男生的学号及平均成绩存入 S_G中。
2、插入子查询的结果,
一、插入操作例题
INSERT INTO S-G(S#,AVG-G)
(SELECT S#,AVG(ALL GRADE)
FROM SC
WHERE S# IN
(SELECT S#
FROM S
WHERE SEX=‘男 ’ )
GROUP BY S#
HAVING AVG(ALL GRADE)>80);
二、删除操作格式,DELETE FROM 表名
[WHERE 条件 ];
只能对整个元组操作,不能只删除某些属性上的值
只能对一个关系起作用,若要从多个关系中删除元组,则必须对每个关系分别执行删除命令
从关系 r 中删除满足 P的元组,只是删除数据,
而不是定义例 1,删除学号为 ‘ 95019’的学生。
1、删除单个元组,
二、删除操作
DELETE FROM SC
WHERE S# = '95019';
DELETE FROM S
WHERE S# = '95019';
例 2,删除选课但无成绩的学生的选课信息
2、删除多个元组,
二、删除操作
DELETE FROM SC
WHERE GRADE IS NULL;
DELETE FROM SC 清空 SC表例 3,删除选修 ‘ C4’且成绩小于该课程的平均成绩的记录
3、带子查询的删除语句:
二、删除操作
DELETE FROM SC
WHERE C#=‘C4’ AND G <
(SELECT AVG(ALL GRADE)
FROM SC
WHERE C#=‘C4’) ;
三、修改操作格式 1,UPDATE 表名 [别名 ]
SET 列名 = 表达式,…
[WHERE 条件 ];
格式 2,UPDATE 表名 [别名 ]
SET (列名,… ) = (子查询 )
[WHERE 条件 ];
例 1,名为 MARTIN的职工的工种改为 MANAGER,
工资增加收入 20%,
1、修改单个元组的值,
三、修改操作
UPDATE EMP
SET JOB=‘MANAGER’,SAL= SAL*1.2
WHERE NAME = ‘MARTIN’;
例 2,将所有学生的年龄增加 1岁
2、修改多个元组的值,
三、修改操作
UPDATE S
SET SA=SA+1;
例 3,工种为 SALESMEN的职工的工资改为工种平均工资的 110%,佣金为最低值。
3、带子查询的修改语句:
三、修改操作
UPDATE EMP
SET (SAL,COMM)=
(SELECT 1.1*AVG(ALL SAL),MIN(COMM)
FROM EMP
WHERE JOB=‘SALESMEN’)
WHERE JOB=‘SALESMEN’;
例 4,计算机系全体学生成绩上浮 15%
3、带子查询的修改语句:
三、修改操作
UPDATE SC
SET GRADE=GRADE*1.15,
WHERE S# IN
(SELECT S#
FROM S
WHERE SD=‘CS’);
数据库上机实验操作说明
1,win2000 登陆
2,在开始菜单 /程序 -----Microsoft SQL 7.0 / Query Analyzer
SQL SERVER,f3-svr
Login Name,USER2
Password,USER2
connection information 选择第二个选项 ------SQLSERVER
然后按 OK
3,STU1,WORK1数据库中,
S,C,SC ; DEPT,EMP,SALGRADE
F3-SVR
SQL SERVER
CONNECTION
USER2
USER2
选择数据库数据库查询 SELECT
数据定义 CREATE,DROP,ALTER
数据操纵 INSERT,UPDATE,DELETE
数据控制 GRANT,REVOKE
SQL功能 动词


§ 3.4 数据定义一、定义基本表 CREATE TABLE
二、删除基本表 DROP TABLE
三、修改基本表 ALTER TABLE
四、定义索引 CREATE INDEX
五、删除索引 DROP INDEX
一、定义基本表格式 1,CREATE TABLE 表名
(列名 类型 (长度 ) [NOT NULL]
[DEFAULT {常量 |系统变量 |NULL}]
[列约束 ],… … )
[PRIMARY KEY (列名,… )]
[FOREIGN KEY (列名,… )
REFERENCES 表名 (列名,… )]
[CHECK 条件 ];
建立一个新表,表中无记录一、定义基本表格式 2,CREATE TABLE 表名
[(列名 [NOT NULL],… )]
[PRIMARY KEY (列名,… )]
[FOREIGN KEY (列名,… )
REFERENCES 表名 1(列名,… )]
AS 子查询
建立一个带有子查询结果记录的新表,
例题
CREATE TABLE S
( S# CHAR(6) NOT NULL,
SNAME CHAR(8) NOT NULL,
SAGE SMALLINT,
SD CHAR(10),
SEX CHAR(2) DEFAULT ‘男 ’
CHECK((SEX='男 ') OR (SEX='女 ')))
PRIMARY KEY (S#);
例,建立学生 S、课程 C、选课 SC三个表
S表:
例题
CREATE TABLE C
(C# CHAR(6) NOT NULL,
CNAME CHAR(30) NOT NULL,
TNAME CHAR(8),
PC# CHAR(6))
PRIMARY KEY (C#);
例,建立学生 S、课程 C、选课 SC三个表
C表:
例题
CREATE TABLE SC
(S# CHAR(6) NOT NULL,
C# CHAR(6) NOT NULL,
GR SMALLINT DEFAULT NULL)
PRIMARY KEY (S#,C#)
FOREIGN KEY (S#) REFERENCES S(S#)
FOREIGN KEY (C#) REFERENCES C(C#)
CHECK (GR IS NULL)
OR (GR BETWEEN O AND 100);
例,建立学生 S、课程 C、选课 SC三个表
SC表:
例题例,设关系 S_G(S#,AVG_G),把平均成绩大于
80的男生的学号及平均成绩存入 S_G中。
CREATE TABLE S_G
(S# CHAR(6) NOT NULL,
AVG_G SMALLINT DEFAULT NULL)
AS
(SELECT S#,AVG(ALL GRADE)
FROM SC
WHERE S# IN
(SELECT S#
FROM S
WHERE SEX=‘男 ’ )
GROUP BY S#
HAVING AVG(ALL GRADE)>80)
二、删除基本表格式,DROP TABLE 表名
[CASCADE|RESTRICT];
删除一个表,及与该表相关的索引、视图、码和外部码。
CASCADE 连同引用该表的视图、完整性约束一起自动撤消
RESTRICT无引用时,才可撤消三、修改基本表
改变表名
增加列
改变列的数据类型
删除列的约束
删除列
改变列名
基本表的修改操作:
三、修改基本表格式,ALTER TABLE 表名
[ADD 新列名 类型 (长度 )[NOT NULL]
[列约束 ],… ]
[MODIFY 旧列名 类型 (长度 )]
[DROP 列约束 ]
[RENAME 旧表名 TO 新表名 ]
增加新列,修改列,删除列的完整性约束;
改变表名及列名。
例题例 1,在 S表中增加一个入学时间,为日期型
ALETR TABLE S ADD SCOME DATE;
例 2,把 SA列的类型改为半字长整数
ALETR TABLE S MODIFY SA SMALLINT;
例 3,删除对 SN列的唯一约束
ALETR TABLE S DROP UNIQUE(SN);
删除列、改变列名
对 删除列、改变列名 的操作,可采取如下步骤实现:
1)CREATE TABLE … AS (子查询 )建一新表
2)删除旧表
3)改变表名四、定义索引格式:
CREATE[UNIQUE][CLUSTER] INDEX 索引名
ON 表名 (列名 [ASC|DESC],… );
对指定的表的列建立索引,
UNIQUE 表示索引值唯一
CLUSTER 表示索引是聚簇索引
索引一旦建立,交由系统使用和维护例题
CREATE UNIQUE INDEX SIDX ON S(S# ASC);
CREATE CLUSTER INDEX SNCDX
ON S(SNAME ASC);
CREATE UNIQUE INDEX CIDX ON C(C# ASC);
CREATE UNIQUE INDEX SCIDX
ON SC(S# ASC,C# DESC);
五、删除索引格式:
DROP INDEX 索引名;
例,DROP INDEX CIDX;
§ 3.5 数据控制一、授 权 GRANT
二、收回权限 REVOKE
一、授 权对象 对象类型 操作权限属性列 TABLE SELECT,INSERT,UPDATE,DELETE,ALL PRIVILEGES
视图 TABLE SELECT,INSERT,UPDATE,DELETE,ALL PRIVILEGES
基本表 TABLE
SELECT,INSERT,UPDATE,
ALTER,INDEX,DELETE ALL
PRIVILEGES
数据库 DATABASE CREATETAB
1,DATABASE:
GRANT CREATETAB
ON DATABASE 数据库名
TO {用户名,… |PUBLIC}
[WITH GRANT OPTION];
授予用户建立表的权限
由 DBA授权,只有 CREATETAB一种权限
WITH GRANT OPTION允许用户转授权 (权限传播 )
PUBLIC表示所有用户格式:
2,TABLE级的基本表
GRANT[{SELECT|INSERT|UPDATE|DELETE
|ALTER|INDEX|ALL PRIVILEGES}]
ON TABLE 表名
TO {用户名,… |PUBLIC}
[WITH GRANT OPTION];
授予用户对表的操作权限
由拥有该表的用户授权格式:
3,TABLE级的视图 (VIEW)
GRANT{SELECT|INSERT|UPDATE|
DELETE|ALL PRIVILEGES}
ON TABLE 视图名
TO {用户名,… |PUBLIC}
[WITH GRANT OPTION];
授予用户对视图的操作权限
由拥有该视图的用户授权格式:
4,TABLE级的列
GRANT{SELECT|INSERT|UPDATE|DELETE|
ALL PRIVILEGES } (列名,…)
ON TABLE {表名 |视图名 }
TO {用户名,… |PUBLIC}
[WITH GRANT OPTION];
授予用户对列的操作权限
由拥有该表或视图的用户授权格式:
例题例 1,GRANT CREATETAB
ON DATABASE 教学系统
TO USER1;
例 2,GRANT SELECT,INSERT
ON TABLE SC
TO USER1,USER2,USER5
WITH GARNT OPTION;
例 3,GRANT ALL PRIVILEGES
ON TABLE SC
TO USER3,USER4,USER7;
例题例 4,把查询 Stu表和修改学生学号的权限授给用户 U4
GRANT UPDATE(Sno),SELECT
ON TABLE Stu
TO U4;
二,ORACLE授权机制在 ORACLE 中对用户的授权分为系统级、表级、视图级
1,系统级:
格式,GRANT [CONNECT[,RESOURCE[,DBA]]]
TO {用户名,… |PUBLIC}
[IDENTIFIED BY 口令,… ];
作用,授予用户对 ORACLE系统的操作权限
CONNECT,允许用户登录数据库,在获得表级或视图级授权后可作相应操作,
但不能建立表 (CREATE TABLE)
RESOURCE,允许建表
DBA,超级用户
2、表级:格式与标准 SQL类似
3、表级:格式与标准 SQL类似例:
GRANT CONNECT,RESOURCE TO XUNS;
GRANT TO USER6 IDENTIFIED BY QWE;
三、收回授权由 DBA或授于 DBA权限的用户对其他用户进行权限回收。
1,格式,REVOKE CREATETAB
ON DATABASE 数据库名
FROM {用户名,… |PUBLIC};
2,格式,REVOKE {权限列表 }
ON TABLE {表名 |视图名 }
FROM {用户名,… |PUBLIC};
3,格式,REVORE {权限列表 } (列名,… )
ON TABLE {表名 |视图名 }
FROM {用户名,… |PUBLIC};
4,格式,REVOKE (DBA[,RESOURCE
[,CONNECT]])
FROM {用户名,… |PUBLIC};
例题例 1 把用户 U4修改学生学号的权限收回
REVOKE UPDATE(Sno) ON TABLE Stu FROM U4;
例 2 收回所有用户对表 SC的查询权限
REVOKE SELECT ON TABLE SC FROM PUBLIC;
例 3 把用户 U5对 SC表的 INSERT权限收回
REVOKE INSERT ON TABLE SC FROM U5;
四、审计 (AUDIT)
以 ORACLE为例,分为系统级审计和用户级审计两种
1、系统级审计,由 DBA进行,可监测登录要求,GRANT,REVOKE及其他数据库级的操作
2、用户级审计,由用户设置,主要针对用户自己创建的表或视图进行审计,监测对表或视图的访问及其他操作。
3、设置审计:
格式,AUDIT 操作列表 ON
{表名 |视图名 |SYSTEM}
4、取消审计:
格式,NOAUDIT 操作列表 ON
{表名 |视图名 |SYSTEM}
5、审计结果存放:
内容在数据字典表 SYS.AUDIT_TRAIL中;
可用 SELECT * FROM SYS.AUDIT_TRAIL; 查看。
§ 3.6 视图视图是从一个或几个表 (或视图 )导出的一个特殊的表 。
视图是一个虚表
数据库中只存放视图的定义
视图对应的数据仍存放在原来的表中
随着表中数据的变化,视图的数据随之改变 。
对视图的查询与基本表一样
对视图的更新将受到一定的限制视图一、视图概念二、定义、删除视图三、查询视图四、更新视图五、视图的作用一、视图概念视 图3.6
视图是一个虚表
数据库中只存放视图的定义
视图对应的数据仍存放在原来的表中
随着表中数据的变化,视图的数据随之改变。
对视图的查询与基本表一样
对视图的更新将受到一定的限制基本表 1 基本表 2
视图视图概念示意图二、视图定义视 图3.6
1、建立视图格式,CREATE VIEW 视图名 [(列名,… )]
AS 子查询
[WITH {CHECK OPTION|READ ONLY}];
表示视图不可更新下述必须指定全部列名:
某个目标列是组函数或表达式
多表连接时,目标列中出现同名列
不用原基本表的列名作为视图名
在定义视图时要么指定全部视图列,要么全部省略不写;如果省略了视图的属性列名,则视图的列名与子查询列名相同。
子查询中通常不包含 ORDER BY和 DISTINCT子句。
虚拟列:经过各种计算派生出的数据所设置的派生属性列。
二、视图定义视 图3.6
2、视图分类行列子集视图,从单个基本表导出,保留基本表的码,但去掉其它的某些列和部分行的视图。
表 达 式 视 图,带虚拟列的视图。
分 组 视 图,子查询目标表带有组函数或子查询带有 GROUP BY
子句的视图。
例 1,建立计算机系学生视图
CREATE VIEW CS_S
AS (SELECT S#,SN,SEX,SA
FROM S
WHERE SD=‘CS’)
WITH CHECK OPTION;
(行列子集视图 )
例 2,建立计算机系选修 ‘ 计算机体系结构 ’ 课程的学生视图
CREATE VIEW CS_SCA(S#,NAME,GR)
AS SELECT S.S#,SN,GR
FROM S,SC,C
WHERE S.S#=SC.S#
AND C.C#=SC.C#
AND S.SD=‘CS’
AND CN=‘计算机体系结构 ’ ;
例 3,建立学生出生年份的视图
CREATE VIEW
BT_S(SNO,NAME,BIRTH)
AS SELECT S#,SN,2003-SA
FROM S;
(表达式视图 )
(虚拟列 )
例 4,建立学生平均成绩视图
CREATE VIEW S_AVG_G(SNO,AVG_G)
AS SELECT S#,AVG(ALL GR)
FROM SC
GROUP BY S#;
(分组视图 )
三、查询视图视 图3.6
视图消解 (View Resolution)
在对视图查询时,DBMS将进行有效性检查
(表及视图)。若存在,则从数据字典中 取出视图定义,并把定义中的子查询与用户查询结合起来 转换为等价的对基本表的查询,然后再执行。
例 1,求计算机系年龄小于 20的学生
SELECT S#,SN
FROM CS_S
WHERE SA<20;
视图消解
SELECT S#,SN
FROM S
WHERE SD=‘CS’ AND SA<20;
例 2,求计算机系选修 ‘ C2’课程的学生
SELECT S#,SN
FROM CS_S,SC
WHERE CS_S.S#=SC.S#
AND SC.C#=‘C2’;
例 3,在学生平均成绩视图 S_AVG_G中查询平均成绩在 90分以上的学生号及成绩
SELECT *
FROM S_AVG_G
WHERE AVG_G>=90;
(系统转换后 )
SELECT S#,AVG( ALL GR)
FROM SC
WHERE AVG(ALL GR)>=90
GROUP BY S#;
SELECT S#,AVG(ALL GR)
FROM SC
GROUP BY S#
HAVING AVG(ALL GR)>=90;
(正确的转换结果 )
四、更新视图视 图3.6
1、更新视图即通过视图插入 (INSERT)、删除
(DELETE)和修改 (UPDATE)数据,实质上转换为对基本表的更新。
2、为了防止用户对超出视图范围的基本表的数据进行操作,在定义视图时,应加上 WITH CHECK
OPTION子句,则在视图上更新数据时,DBMS将检查视图定义中的条件,不满足将拒绝执行。
例 1,SC_S视图的 ‘ 刘茜 ’ 的年龄改为 20
转换前:
UPDATE CS_S
SET SA=20
WHERE SN=‘刘茜 ’ ;
转换后:
UPDATE S
SET SA=20
WHERE SN=‘刘茜 ’
AND SD=‘CS’;
例 2,在 CS_S中插入 ‘ 990075,吴迪,女,19’
的学生记录转换前:
INSERT INT CS_S
VALUES(‘990075’,
‘ 吴迪 ’,‘女 ’,19);
转换后:
INSERT INTO S
VALUES(‘990075’,‘吴迪 ’,19,‘CS’,‘女
’ );
例 3:删除 CS_S中年龄大于 23的学生转换前:
DELETE FROM CS_S
WHERE SA>23;
转换后:
DELETE FROM S
WHERE SA>23
AND SD=’CS’;
例 4,修改‘ 990075’学生平均成绩为 90
转换前:
UPDATE S_AVG_G
SET AVG_G=90
WHERE SNO=’990075’;
不可转换。
左边程序操作失败。
3,一般情况下,行列子集视图是可更新的,所以各 RDBS均只允许对行列子集视图进行更新 。
4,不可更新的视图(各系统不太一致)
由多个表导出的视图,不可更新
视图的列来自表达式或常数,不可插,改,可删
视图列是来自组函数,不可更新
视图定义中含有 GROUP BY子句,不可更新
视图定义中内层嵌套的表与查询目标同一个表,
不可更新
在不允许更新的视图上定义的视图,不可更新五、视图优点视 图3.6
提供数据的逻辑独立性
提供数据的安全保护功能
简化用户的操作
(对系统构成的视图,用户不必关心各表间的联系)
同一数据多种用法
§ 3.7 嵌入式 SQL语句
3.7.1 嵌入式 SQL的一般形式
3.7.2 嵌入式 SQL语句与主语言之间的通信
3.7.3 不用游标的 SQL语句
3.7.4 使用游标的 SQL语句
3.7.5 动态 SQL简介
SQL语言提供了两种不同的使用方式:
交互式
嵌入式
为什么要引入嵌入式 SQL
SQL语言是非过程性语言
事务处理应用需要高级语言
这两种方式细节上有差别,在程序设计的环境下,SQL语句要做某些必要的扩充
3.7 嵌入式 SQL语句嵌入式 SQL
将 SQL语言嵌入到某种高级语言中使用,利用高级语言的过程性结构来弥补
SQL语言实现复杂应用方面的不足。
这种方式下使用的 SQL语言称为嵌入式 SQL(Embedded SQL)。
嵌入 SQL的高级语言称为主语言或宿主语言。
嵌入式 SQL的一般形式3.7.1
为了区分 SQL语句与主语言语句,需要,
前缀,EXEC SQL
结束标志:随主语言的不同而不同
以 C为主语言的嵌入式 SQL语句的一般形式
EXEC SQL <SQL语句 > ;
例,EXEC SQL DROP TABLE Student ;
以 COBOL作为主语言的嵌入式 SQL语句的一般形式
EXEC SQL <SQL语句 > END-EXEC
例,EXEC SQL DROP TABLE Student END-EXEC
嵌入式 SQL的一般形式3.7.1
说明性语句嵌入 SQL语句 数据定义可执行语句 数据控制数据操纵
允许出现可执行的高级语言语句的地方,都可以写可执行
SQL语句
允许出现说明语句的地方,都可以写说明性 SQL语句嵌入式 SQL语句与主语言之间的通信3.7.2
1,SQL通信区向主语言传递 SQL语句的执行状态信息主语言能够据此控制程序流程
2,主变量
1)主语言向 SQL语句提供参数
2)将 SQL语句查询数据库的结果交主语言进一步处理
3,游标解决集合性操作语言与过程性操作语言的不匹配
1,SQL 通信区? SQLCA,SQL Communication Area
SQLCA是一个数据结构
SQLCA的用途
SQL语句执行后,DBMS反馈给应用程序信息
描述系统当前工作状态
描述运行环境
这些信息将送到 SQL通信区 SQLCA中
应用程序从 SQLCA中取出这些状态信息,据此决定接下来执行的语句嵌入式 SQL语句与主语言之间的通信3.7.2
DBMS工作状态、运行信息 SQLCA应用程序 后继语句
1,SQL 通信区嵌入式 SQL语句与主语言之间的通信3.7.2
SQLCA的内容
与所执行的 SQL语句有关
与该 SQL语句的执行情况有关例:在执行删除语句 DELETE后,不同的执行情况,SQLCA
中有不同的信息:
违反数据保护规则,操作拒绝
没有满足条件的行,一行也没有删除
成功删除,并有删除的行数
无条件删除警告信息
由于各种原因,执行出错
1,SQL 通信区
SQLCA的使用方法
SQL语句执行后,DBMS反馈给应用程序信息
描述系统当前工作状态
描述运行环境
这些信息将送到 SQL通信区 SQLCA中
应用程序从 SQLCA中取出这些状态信息,据此决定接下来执行的语句嵌入式 SQL语句与主语言之间的通信3.7.2
SQLCA在应用程序中用
EXEC SQL INCLUDE SQLCA 加以定义
SQLCODE,SQLCA中的一个存放返回代码的变量;每次 SQL语句执行后均返回一个值,表示该 SQL语句执行是否成功,以及不成功的原因。
通常用预定义的常量 SUCCESS表示成功;
否则在 SQLCODE中将存放错误代码。
2,主变量嵌入式 SQL语句与主语言之间的通信3.7.2
什么是主变量
嵌入式 SQL语句中可以使用主语言的程序变量来输入或输出数据
在 SQL语句中使用的主语言程序变量简称为主变量( Host Variable)
2,主变量嵌入式 SQL语句与主语言之间的通信3.7.2
主变量的类型
输入主变量
由应用程序对其赋值,SQL语句引用
输出主变量
由 SQL语句赋值或设置状态信息,返回给应用程序
一个主变量有可能既是输入主变量又是输出主变量
2,主变量嵌入式 SQL语句与主语言之间的通信3.7.2
主变量的用途
输入主变量
指定向数据库中插入的数据
将数据库中的数据修改为指定值
指定执行的操作
指定 WHERE子句或 HAVING子句中的条件
输出主变量
获取 SQL语句的结果数据
获取 SQL语句的执行状态
2,主变量嵌入式 SQL语句与主语言之间的通信3.7.2
指示变量
一个主变量可以附带一个指示变量( Indicator
Variable)
什么是指示变量
整型变量
用来,指示,所指主变量的值或条件
指示变量的用途
输入主变量可以利用指示变量赋空值
输出主变量可以利用指示变量检测出是否空值,值是否被截断
2,主变量嵌入式 SQL语句与主语言之间的通信3.7.2
定义主变量:
EXEC SQL BEGIN DECLARE SECTION
........,
........,(说明主变量和指示变量 )
.........
EXEC SQL END DECLARE SECTION
引用主变量,在 SQL语句中引用主变量和指示变量时,其变量名前应加 ‘,’ 。
3,游 标嵌入式 SQL语句与主语言之间的通信3.7.2
为什么要使用游标
SQL语言与主语言具有不同数据处理方式
SQL语言是面向集合的,一条 SQL语句原则上可以产生或处理多条记录
主语言是面向记录的,一组主变量一次只能存放一条记录
( cursor)
3,游 标嵌入式 SQL语句与主语言之间的通信3.7.2
什么是游标
游标是系统为用户开设的一个数据缓冲区,存放 SQL语句的执行结果
每个游标区都有一个名字
用户可以用 SQL语句逐一从游标中获取记录,
并赋给主变量,交由主语言进一步处理
( cursor)
实例嵌入式 SQL语句与主语言之间的通信3.7.2
例:带有嵌入式 SQL的一小段 C程序
............
EXEC SQL INCLUDE SQLCA;
/* (1) 定义 SQL通信区 */
EXEC SQL BEGIN DECLARE SECTION;
/* (2) 说明主变量 */
CHAR title_id(7);
CHAR title(81);
INT royalty;
EXEC SQL END DECLARE SECTION;
嵌入式 SQL语句与主语言之间的通信3.7.2
main()
{
EXEC SQL DECLARE C1 CURSOR FOR
SELECT tit_id,tit,roy FROM titles;
/* (3) 游标操作(定义游标) */
/* 从 titles表中查询 tit_id,tit,roy */
EXEC SQL OPEN C1;
/* (4) 游标操作(打开游标) */
嵌入式 SQL语句与主语言之间的通信3.7.2
for(;;)
{
EXEC SQL FETCH C1 INTO,title_id,:title,:royalty;
/* (5) 游标操作(将当前数据放入主变量并推进游标指针) */
if (sqlca.sqlcode <> SUCCESS)
/* (6) 利用 SQLCA中的状态信息决定何时退出循环 */
break;
printf("Title ID,%s,Royalty,%d",:title_id,:royalty);
printf("Title,%s",:title);
/* 打印查询结果 */
}
EXEC SQL CLOSE C1;
/* (7) 游标操作(关闭游标) */
}
不使用游标的 SQL语句3.7.3
不用游标的 SQL语句的种类
说明性语句
数据定义语句
数据控制语句
查询结果为单记录的 SELECT语句
非 CURRENT形式的 UPDATE语句
非 CURRENT形式的 DELETE语句
INSERT语句不使用游标的 SQL语句3.7.3
说明性语句是专为在嵌入式 SQL中说明主变量、
SQLCA等而设置的
说明主变量
1,EXEC SQL BEGIN DECLARE SECTION;
2,EXEC SQL END DECLARE SECTION;
这两条语句必须配对出现,相当于一个括号,两条语句中间是主变量的说明
说明 SQLCA
3,EXEC SQL INCLUDE SQLCA
一、说明性语句不使用游标的 SQL语句3.7.3
例 1 建立一个,学生,表 Student
EXEC SQL CREATE TABLE Student
(Sno CHAR(5) NOT NULL UNIQUE,
Sname CHAR(20),
Ssex CHAR(1),
Sage INT,
Sdept CHAR(15));
二、数据定义语句不使用游标的 SQL语句3.7.3
数据定义语句中不允许使用主变量例:下列语句是错误的
EXEC SQL DROP
TABLE,table_name;
二、数据定义语句不使用游标的 SQL语句3.7.3
例 2 把查询 Student表权限授给用户 U1
EXEC SQL GRANT SELECT ON
TABLE Student TO U1;
三、数据控制语句不使用游标的 SQL语句3.7.3
语句格式
EXEC SQL SELECT [ALL|DISTINCT]
<目标列表达式 >[,<目标列表达式 >]...
INTO <主变量 >[<指示变量 >]
[,<主变量 >[<指示变量 >]]..,
FROM <表名或视图名 >[,<表名或视图名 >],..
[WHERE <条件表达式 >]
[GROUP BY <列名 1> [HAVING <条件表达式 >]]
[ORDER BY <列名 2> [ASC|DESC]];
四、查询结果为单记录的 SELECT语句不使用游标的 SQL语句3.7.3
例 3 根据学生号码查询学生信息。
假设已将要查询的学生的学号赋给了主变量 givensno
EXEC SQL SELECT Sno,Sname,Ssex,Sage,Sdept
INTO,Hsno,:Hname,:Hsex,:Hage,:Hdept
FROM Student
WHERE Sno=:givensno;
Hsno,Hname,Hsex,Hage,Hdept和 givensno均是主变量,并均已在前面的程序中说明过了。
四、查询结果为单记录的 SELECT语句不使用游标的 SQL语句3.7.3
例 4 查询某个学生选修某门课程的成绩。
假设已将要查询的学生的学号赋给了主变量
givensno,将课程号赋给了主变量 givencno。
EXEC SQL SELECT Sno,Cno,Grade
INTO,Hsno,:Hcno,:Hgrade:Gradeid
FROM SC
WHERE Sno=:givensno AND Cno=:givencno;
四、查询结果为单记录的 SELECT语句不使用游标的 SQL语句3.7.3
非 CURRENT形式的 UPDATE语句
使用主变量
SET子句
WHERE子句
使用指示变量
SET子句
非 CURRENT形式的 UPDATE语句可以操作多条元组五、非 CURRENT形式的 UPDATE语句不使用游标的 SQL语句3.7.3
例 5 将全体学生 1号课程的考试成绩增加若干分。
假设增加的分数已赋给主变量 Raise
EXEC SQL UPDATE SC
SET Grade=Grade+:Raise
WHERE Cno='1';
五、非 CURRENT形式的 UPDATE语句不使用游标的 SQL语句3.7.3
例 6 修改某个学生 1号课程的成绩。
假设该学生的学号已赋给主变量 givensno,
修改后的成绩已赋给主变量 newgrade。
EXEC SQL UPDATE SC
SET Grade=:newgrade
WHERE Sno=:givensno;
五、非 CURRENT形式的 UPDATE语句不使用游标的 SQL语句3.7.3
例 7 将计算机系全体学生年龄置 NULL值
Sageid=-1;
EXEC SQL UPDATE Student
SET Sage=:Raise:Sageid
WHERE Sdept='CS';
五、非 CURRENT形式的 UPDATE语句不使用游标的 SQL语句3.7.3
非 CURRENT形式的 DELETE语句
使用主变量
WHERE子句
非 CURRENT形式的 DELETE语句可以操作多条元组六、非 CURRENT形式的 DELETE语句不使用游标的 SQL语句3.7.3
例 8 某个学生退学了,现要将有关他的所有选课记录删除掉。
假设该学生的姓名已赋给主变量 stdname
EXEC SQL DELETE
FROM SC
WHERE Sno=
(SELECT Sno
FROM Student
WHERE Sname=:stdname);
六、非 CURRENT形式的 DELETE语句不使用游标的 SQL语句3.7.3
非 CURRENT形式的 INSERT语句
使用主变量
VALUES子句
使用指示变量
VALUES子句
非 CURRENT形式的 INSERT语句一次只能输入一条元组七,INSERT语句不使用游标的 SQL语句3.7.3
例 9 某个学生新选修了某门课程,将有关记录插入 SC表假设学生的学号已赋给主变量 stdno,课程号已赋给主变量 couno
gradeid=-1;
EXEC SQL INSERT
INTO SC(Sno,Cno,Grade)
VALUES(:stdno,:couno,:gr:gradeid);
由于该学生刚选修课程,尚未考试,因此成绩列为空。所以本例中用指示变量指示相应的主变量为空值。
七,INSERT语句使用游标的 SQL语句3.7.4
必须使用游标的 SQL语句
查询结果为多条记录的 SELECT语句
CURRENT形式的 UPDATE语句
CURRENT形式的 DELETE语句使用游标的 SQL语句3.7.4
使用游标的步骤
1,说明游标
2,打开游标
3,移动游标指针,然后取当前记录
4,关闭游标一,查询结果为多条记录的 SELECT语句使用游标的 SQL语句3.7.4
使用 DECLARE语句
语句格式
EXEC SQL DECLARE <游标名 > CURSOR
FOR <SELECT语句 >;
功能
是一条说明性语句,这时 DBMS并不执行 SELECT指定的查询操作。
1,说明游标使用游标的 SQL语句3.7.4
使用 OPEN语句
语句格式
EXEC SQL OPEN <游标名 >;
功能
打开游标实际上是执行相应的 SELECT语句,把所有满足查询条件的记录从指定表取到缓冲区中
这时游标处于活动状态,指针指向查询结果集中第一条记录之前
2,打开游标使用游标的 SQL语句3.7.4
使用 FETCH语句
语句格式
EXEC SQL FETCH [[NEXT|PRIOR|
FIRST|LAST] FROM] <游标名 >
INTO <主变量 >[<指示变量 >]
[,<主变量 >[<指示变量 >]]...;
3,移动游标指针,然后取当前记录使用游标的 SQL语句3.7.4
功能
指定方向推动游标指针,然后将缓冲区中的当前记录取出来送至主变量供主语言进一步处理。
NEXT|PRIOR|FIRST|LAST:指定推动游标指针的方式。
NEXT:向前推进一条记录
PRIOR:向回退一条记录
FIRST:推向第一条记录
LAST:推向最后一条记录
缺省值为 NEXT
3,移动游标指针,然后取当前记录使用游标的 SQL语句3.7.4
说明
(1) 主变量必须与 SELECT语句中的目标列表达式具有一一对应关系
(2) FETCH语句通常用在一个循环结构中,通过循环执行
FETCH语句逐条取出结果集中的行进行处理
(3) 为进一步方便用户处理数据,现在一些关系数据库管理系统对 FETCH语句做了扩充,允许用户向任意方向以任意步长移动游标指针
3,移动游标指针,然后取当前记录使用游标的 SQL语句3.7.4
使用 CLOSE语句
语句格式
EXEC SQL CLOSE <游标名 >;
功能
关闭游标,释放结果集占用的缓冲区及其他资源
说明
游标被关闭后,就不再和原来的查询结果集相联系
被关闭的游标可以再次被打开,与新的查询结果相联系
4,关闭游标例 1 查询某个系全体学生的信息(学号、姓名、性别和年龄)。要查询的系名由用户在程序运行过程中指定,
放在主变量 deptname中
.....,
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
......
/* 说明主变量 deptname,HSno,HSname,HSsex,HSage等 */
......
......
EXEC SQL END DECLARE SECTION;
......
......
gets(deptname); /* 为主变量 deptname赋值 */
......
EXEC SQL DECLARE SX CURSOR FOR
SELECT Sno,Sname,Ssex,Sage
FROM Student
WHERE SDept=:deptname; /* 说明游标 */
EXEC SQL OPEN SX /* 打开游标 */
WHILE(1) /* 用循环结构逐条处理结果集中的记录 */
{
EXEC SQL FETCH SX
INTO,HSno,:HSname,:HSsex,:HSage;
/* 将游标指针向前推进一行,然后从结果集中取当前行,送相应主变量 */
if (sqlca.sqlcode <> SUCCESS)
break;
/* 若所有查询结果均已处理完或出现
SQL语句错误,则退出循环 */
/* 由主语言语句进行进一步处理 */
......
......
};
EXEC SQL CLOSE SX; /* 关闭游标 */
......
......
例 2 查询某些系全体学生的信息。
......
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
......
/* 说明主变量 deptname,HSno,HSname,HSsex,HSage等 */
......
EXEC SQL END DECLARE SECTION;
......
EXEC SQL DECLARE SX CURSOR FOR
SELECT Sno,Sname,Ssex,Sage
FROM Student
WHERE SDept=:deptname; /* 说明游标 */
WHILE (gets(deptname)!=NULL)
/* 接收主变量 deptname的值 */
{
/* 下面开始处理 deptname指定系的学生信息,
每次循环中 deptname可具有不同的值 */
EXEC SQL OPEN SX /* 打开游标 */
WHILE (1) { /* 用循环结构逐条处理结果集中的记录 */
EXEC SQL FETCH SX
INTO,HSno,:HSname,:HSsex,:HSage;
/* 将游标指针向前推进一行,然后从结果集中取当前行,送相应主变量 */
if (sqlca.sqlcode <> SUCCESS)
break;
/* 若所有查询结果均已处理完或出现
SQL语句错误,则退出循环 */
/* 由主语言语句进行进一步处理 */
......
......
}; /* 内循环结束 */
EXEC SQL CLOSE SX; /* 关闭游标 */
}; /* 外循环结束 */
......
......
动态 SQL简介3.7.5
用户可以在程序运行过程中根据实际需要输入 WHERE
子句或 HAVING子句中某些变量的 值 。
语句中主变量的 个数与数据类型 在预编译时都是确定的,只有是主变量的 值 是程序运行过程中动态输入的。
静态 SQL特点动态 SQL简介3.7.5
1,什么是动态嵌入式 SQL
动态 SQL方法允许在程序运行过程中临时,组装,SQL语句。
2,应用范围
在 预编译 时下列信息不能确定时
SQL语句正文
主变量个数
主变量的数据类型
SQL语句中引用的数据库对象(列、索引、基本表、视图等)
动态 SQL
动态 SQL简介3.7.5
3,动态 SQL的形式
语句可变
临时构造完整的 SQL语句
条件可变
WHERE子句中的条件
HAVING短语中的条件
数据库对象、查询条件均可变
SELECT子句中的列名
FROM子句中的表名或视图名
WHERE子句中的条件
HAVING短语中的条件动态 SQL
动态 SQL简介3.7.5
4,常用动态 SQL语句
EXECUTE IMMEDIATE
PREPARE
EXECUTE
DESCRIBE
使用动态 SQL技术更多的是涉及程序设计方面的知识,而不是 SQL语言本身动态 SQL
关系数据库标准语言第 3章
§ 3.1 SQL概述
§ 3.2 查询语句
§ 3.3 更新语句
§ 3.4 SQL DDL
§ 3.5 SQL DCL
§ 3.6 视图
§ 3.7 嵌入式 SQL


数据库上机实验操作说明
1,98下在开始菜单中选择注销,重新以相应的用户名登录例如 用户名 user6
密码 pass6
2000下 直接以相应的用户名登录用户名 user6
密码 pass6
注:一机房 user 1~100
2,在开始菜单 /程序 -----Microsoft SQL 7.0 / Query Analyzer
SQL SERVER,server1(第一机房 )
connection information 选择第一个选项 ------Windows NT
然后按 OK
3,sample数据库中,
Student,Course,SC,DEPT,EMP,SALGRADE,
数据库上机实验操作说明
1,win2000 登录
2,在开始菜单 /程序 -----Microsoft SQL 7.0 / Query Analyzer
SQL SERVER,f3-svr
Login Name,USER2
Password,USER2
connection information 选择第二个选项 ------SQLSERVER
然后按 OK
3,STU1,WORK1数据库中,
S,C,SC ; DEPT,EMP,SALGRADE
F3-SVR
SQL SERVER
CONNECTION
USER2
USER2
选择数据库