说在前面
本章习题和答案放在最后,答案是我自己写的,如果与我不一样欢迎留言交流。
1,概论
无所谓,跳吧。
2,数据定义
2.1,建表、改表、删表
建表
create table 表名
(属性名1 类型(长度) 约束,
属性名2 类型(长度) 约束,
..........
PRIMARY KEY(指明哪个属性当主键),
FOREIGN KEY(指明外键) REFERENCES 被参考表名(属性名),
CHECK (写入用户定义约束条件)
);
改表
ALTER包括的操作有三种:增加字段(增字段)、改变类型(改类型)、删除约束(删约束);
增字段:ALTER TABLE 表名 ADD 属性名 类型(长度)约束;
改类型:ALTER TABLE 表名 MODIFY 属性名 类型;
删约束:ALTER TABLE 表名 DROP 约束(属性名);
删表
DROP TABLE 表名;
2.2,建立与删除索引
建立索引
CREATE UNIQUE/CLUSTER INDEX 索引名 ON 表名(属性名 ASC/DESC,...);
这里UNIQUE/CLUSTER表示是唯一值索引还是聚簇索引,缺省值是UNIQUE,对于CLUSTER只用记住每张表只能建立一个聚簇索引,并且聚簇只适用于不常更新的属性。
删除索引
DROP INDEX 索引名;
3,查询
3.1单表查询(单查)
SELECT [ALL/DISTICNT] 属性名,...(这里可以用*代表所有属性,同时可以对属性名使用算术表达式或者集函数)
FROM 表名
WHERE 查询条件(这里门道很多)
ORDER BY 属性名 ASC/DESC
GROUP BY 属性名;
HAVING 条件;
3.2连接查询(连查)
等值与非等值连接
SELECT Student.*,SC.*
FROM Student,SC
WHERE Student.Sno=SC.Sno;
消除重复列后就是自然连接。
自身连接
SELECT FIRST.Cno,SECOND.Cpno
FROM Course First,Course SECOND
WHERE FIRST.Cpno=SECOND.Cno;
外连接
一般情况下连接只会给出符合连接条件的结果,但是外连接会在不符合条件是用空行进行连接,根据左外和右外空行填充在不同位置。
SELECT XXX,XXX,XXX...
FROM Student,SC
WHERE Student.Sno=SC.Sno(*)
这就是右外。
3.3嵌套查询(套查)
IN谓词套查
略。
比较符套查
略。
ANY,ALL套查
略。
EXISTS套查
重中之重,EXISTS可以表达存在量词、全称量词和蕴含。那么应该如何转化?
SELECT Student.Sname
FROM Student
WHERE EXISTS
(SELECT *
FROM SC
WHERE Student.Sno=SC.Sno AND SC.Cno='1'
);
全称量词转化存在量词的转化规则为:
SELECT Student.Sname
FROM Student
WHERE NOT EXISTS
(SELECT *
FROM SC
WHERE SC.Sno=Student.Sno AND SC.Cno='1'
);
蕴含转存在的规则:
SELECT SC.Sno
FROM SC SCX
WHERE NOT EXISTS
(SELECT *
FROM Course
WHERE EXISTS
(SELECT *
FROM SC SCY
WHERE SCY.Sno=95002 AND SCY.Cno=Course.Cno
) AND NOT EXISTS
(SELECT *
FROM SC SCZ
WHERE SCZ.Sno=SCX.Sno AND SCZ.Cno=Course.Cno
))
3.4集合查询(集查)
SQL提供了UNION操作符来讲两个集合求并。
4,数据更新
4.1,插入数据
插入单项:
INSERT
INTO 表名(属性们)
VALUES(值们);
插入子查询结果:
INSERT
INTO 表名(属性们)
子查询;
4.2,修改数据
直接改:
UPDATE 表名
SET 属性=值
WHERE 查询条件
带子查询的改:
UPDATE 表名
SET 属性=值
WHERE 查询条件中带有子查询
4.3,删除数据
直接删:
DELETE
FROM 表名
WHERE 查询条件;
带子查询的删:
DELETE
FROM 表名
WHERE 查询条件中带有子查询;
5,视图
5.1,视图的意义
给不同的用户,不同的数据表现。
5.2,定义视图
创建视图
CREATE VIEW 视图名(属性们)
AS 子查询
[WITH CHECK OPTION];
最后的with check option表示对视图进行增删改时要满足子查询中的条件表达式,可选。
视图名后是否需要指定属性名?三种情况需要指定:1,子查询的SELECT中有集函数;2,子查询的SELECT中存在同名属性;3,你想取个更好的名字。当这三种情况时,需要手动指定。
删除视图
DROP VIEW 视图名;
5.3,查询视图
类似于基本表的查询。
5.4,更新视图
类似于基本表的更新。
6,权限控制
6.1,授权
GRANT 权限们(属性们)
ON 对象类型,对象名们
TO 用户们
[WITH GRANT OPTION]
对象类型如DATABASE,TABLE。
WITH GRANT OPTION意味着可以继续授已有的权给别人,可选。
6.2,收权
REVOKE 权限们(属性们)
ON 对象类型,对象名
FROM 用户们;
收权会链式的把所有间接下放的权限收回。
7,嵌入式SQL
SQL通信区。
主变量,在嵌入式SQL中使用的主程序变量。
游标,逐一访问结果集合的东西。
本章习题
解答:
1,sql语言主要特点包括以下5个:
综合统一。即将DDL(数据库定义语言),DML(数据库操作语言),DCL(数据库控制语言)结合在一起,语法清晰简洁。
高度非过程化。只需写清楚做什么不用写怎么做。
面向集合。就是不需要一条一条的操作。
既可以直接使用,也可以嵌入式使用。
简单易学。
2,SQL的定义功能:关系型数据库支持三级模式。外模式即视图,模式即表,内模式包括索引。所以sql的定义功能包括定义与修改表,定义与修改视图,定义与修改索引。
3,略,自己练习。
4,
(1)求供应工程J1的零件供应商号码SNO。
SELECT SNO
FROM SPJ
WHERE JNO=‘J1’;
(2)求供应商J1零件P1的供应商号码SNO。
SELECT SNO
FROM SPJ
WHERE JNO='J1' AND PNO='P1';
(3)求供应商J1零件为红色的供应商号码SNO。
SELECT SPJ.SNO
FROM SPJ,P
WHERE SPJ.JNO='J1' AND SPJ.PNO = P.PNO AND P.COLOR='红';
(4)求没有使用天津供应商的生产的红色零件的工程号JNO。
这个题有点意思,用连接查询或者嵌套查询都是可以的,我在这里用了嵌套查询,算是检验一下自己是不是真的理解了exist的用法,这里我将关系代数中的全称量词转化成NOT EXIST来完成了表达式的构造。我写的这个如果你不熟悉全称量词和存在量词的表达可能很难看懂,这个题用连接表达会更容易理解一些。
SELECT SPJ.JNO
FROM SPJ
WHERE NOT EXIST
(
SELECT *
FROM S
WHERE S.SNO = SPJ.SNO AND SNO.CITY='天津';
) AND NOT EXIST
(
SELECT *
FROM P
WHERE P.PNO = SPJ.PNO AND P.COLOR = '红';
);
(5)求至少使用了供应商S1所提供的的全部零件的工程号JNO。
这个题应该是全场最佳,代码很有点复杂,涉及到全称量词和蕴含转化为SQL中的存在量词,我先把后面的题做完再补上。
5,
(1)
SELECT SNAME,CITY
FROM S;
(2)
SELECT PNAME,COLOR,WEIGHT
FROM P;
(3)
SELECT JNO
FROM SPJ
WHERE SNO='S1';
(4)
SELECT P.PNAME,SPJ.QTY
FROM SPJ,P
WHERE SPJ.JNO='J2' AND SPJ.PNO = P.PNO;
(5)
SELECT DISTINCT SPJ.PNO
FROM S,SPJ
WHERE S.CITY='上海' AND S.SNO=SPJ.SNO;
(6)
SELECT J.JNAME
FROM J,S,SPJ
WHERE SPJ.JNO = J.JNO AND SPJ.SNO = S.SNO AND S.CITY='上海';
(7)
SELECT J.JNAME
FROM J,S,SPJ
WHERE SPJ.JNO = J.JNO AND SPJ.SNO = S.SNO AND S.CITY != '天津';
(8)
UPDATE P
SET COLOR = '蓝'
WHERE COLOR='红';
(9)
UPDATE SPJ
SET SNO='S3'
WHERE JNO='J4' AND SNO='S5' AND PNO = 'P6';
(10)
DELETE
FROM S
WHERE SNO='S3';
DELETE
FROM SPJ
WHERE SNO='S3';
(11)
INSERT
INTO SPJ
VALUES('S2','J6','P4',200);
6,视图是从一个或几个基本表(或视图)中导出的数据,它与基本表不同,是一张虚表。数据库中只存有视图的定义,视图的数据依然存放在基本表中。对视图的更新操作会受到WITH CHECK OPTION的限制。加上WITH CHECK OPTION之后,更新视图时要满足子查询中的WHERE后面的条件。
7,视图的优点:
1,简化操作
2,多角度看待同一数据
3,为重构数据库逻辑独立性
4,对机密数据提供保护
8,并不是所有的视图都可以更新,因为有些对视图的更新不能转化为有意义的唯一的基本表的更新。比如修改S_G视图中的平均成绩是不允许的,因为无法导致基本表的正确更新。
9,一般来说,行列子集视图都是允许更新的,除此之外还有某些视图理论上是可以更新的(书上也没具体说)。例子举得就是那个S_G的例子。
10,sorry,我不熟悉系统的视图更新。
11,
CREATE VIEW SANJIAN_PROVISION
AS
SELECT SNO,PNO,QTY
FROM SPJ,J
WHERE J.JNAME='三建' AND J.JNO = SPJ.JNO
WITH CHECK OPTION;
SELECT PNO,QTY
FROM SANJIAN_PROVISION;
SELECT *
FROM SANJIAN_PROVISION
WHERE SNO = 'S1';
12,
GRANT INSERT
ON TABLE S
TO 张勇
WITH GRANT OPTION;
GRANT SELECT,UPDATE(QTY)
ON TABLE SPJ
TO 李天明
13,为了区分SQL语句与主程序语句,所有SQL语句前面都必须加上EXEC SQL。
14,SQL语句通过SQL通信区向主语言传递sql执行状况,主语言通过主变量向SQL传递数据。
15,通过游标进行协调。