目录
前言:
笔记来自《文老师软考数据库》教材精讲,精讲视频在b站,某宝都可以找到,个人感觉通俗易懂。
8.1 SQL语言概述
- 数据定义语言DDL:数据结构定义与数据库对象定义的语言,由create、alter、drop三个语法组成。
- 数据操纵语言DML: 实现对数据库的基本操作,包含select、update、insert、delete等语法。
- 数据库语言的分类
● 作为独立语言使用;
● 嵌入到高级语言中使用:嵌入式SQL、宿主语言。 - SQL由以下几个部分组成:
(1)数据定义语言。SQL DDL提供定义关系模式和视图、删除关系和视图修改关系模式的命令。
(2)交互式数据操纵语言。SQLDML 提供查询、插入、删除和修改的命令。
(3)事务控制。SQL 提供定义事务开始和结束的命令。
(4)嵌入式SQL和动态SQL。用于嵌入到某种通用的高级语言(C、C+ +、JavaPL/l、COBOL和VB等)中混合编程。其中,SQL负责操纵数据库,高级语言负责控制程序流程。
(5)完整性。SQLDDL 包括定义数据库中的数据必须满足的完整性约束条件的命令,对于破坏完整性约束条件的更新将被禁止。
(6)权限管理。SQLDDL 中包括说明对关系和视图的访问权限。
8.2 数据库定义
8.2.1 创建表(create table)
CREATE TABLE<表名>(<列名><数据类型>[列级完整性约束条件]
[,<列名><数据类型>[列级完整性约束条件]]...
[,<表级完整性约束条件>]) ;
● 列级完整性约束条件有 NULL (空)和UNTQUE(取值唯一)。
● 表级完整性约束条件有 primary key 和 foreign key 等。
create table stu(sno int not null unique,
sex char(6),
departnum int,
sname char(10),
primary key(sno),
foreign key(departnum) references depart (departnum));
8.2.2 修改表 (alter table)
ALTER TABLE<表名>[ADD<新列名<数据类型>[完整性约束条件]]
[DROP<完整性约束名>]
[MODIFY<列名><数据类型>];
alter table stu add telephone char(11);
alter table stu modify sno char(6);
8.2.3 删除表 (drop table)
DROP TABLE <表名>
drop table stu;
8.2.4 索引
【索引的作用】
(1)通过创建唯一索引,可以保证数据记录的唯一性。
(2)可以大大加快数据检索速度。
(3)可以加速表与表之间的连接,这一点在实现数据的参照完整性方面有特别的意义。
(4)在使用ORDERBY和GROUP BY子句中进行检索数据时,可以显著减少查中分组和排序的时间。
(5)使用索引可以在检索数据的过程中使用优化隐藏器,提高系统性能。
- 索引分为聚集索引和非聚集索引。聚集索引是指索引表中索引项的顺序与表中记录的物理顺序一致的索引。
创建索引
CREATE [UNIQUE] [CLUSTER] INDEX <索引名>ON<表名>(<列名>[<次序>][,<列名>[次序>]]... ) ;
● 次序:可选ASC (升序) 或DSC (降序) ,默认升序。
● UNIQUE:表明此索引的每一个索引值只对应唯一的数据记录。
● CLUSTER:表明要建立的索引是聚簇索引,索引项的顺序是与表中记录的物理顺序一致的索引组织。
删除索引
DROPINDEX<索引名>
8.2.5 视图
视图不是真实存在的基本表,而是一个虚拟表,视图所对应的数据并不实际地以视图结构存储在数据库中,而是存储在视图所引用的表中。使用视图的优点和作用如下:
(1)可以使视图集中数据、简化和定制不同用户对数据库的不同数据要求。
(2)使用视图可以屏蔽数据的复杂性,用户不必了解数据库的结构,就可以方便地使用和管理数据简化数据权限管理和重新组织数据以便输出到其他应用程序中。
(3)视图可以使用户只关心他感兴趣的某些特定数据和所负责的特定任务,而那些不需要的或者无用的数据则不在视图中显示。
(4)视图大大地简化了用户对数据的操作
(5)视图可以让不同的用户以不同的方式看到不同或者相同的数据集。
(6)在某些情况下,由于表中数据量太大因此在表的设计时常将表进行水平或者垂直分割,但表的结构的变化对应用程序产生不良的影响。
(7)视图提供了一个简单而有效的安全机制。
创建视图
CREATE VIEW 视图名(列表名)
AS SELECT 查询子句[WITH CHECK OPTION];
- 子查询可以是任意复杂的 select 语句,但通常不允许含有 order by 和distinct。ewith check option 表示执行 update、insert、delete 操作时保证更新、插入、删除的行满足视图定义中的条件。“
- 组成视图的属性列名或者全部省略或者全部指定。如果省略属性列名,则隐含该视图由 select子查询目标列的主属性组成。
create view cs-stu as select * from stu where depart='cs' with check option;
删除视图
drop view 视图名
drop view cs-stu;
8.3 数据操作
8.3.1 查询语句格式
SELECT [ALL | DISTINCT] <目标列表达式> [目标列表达式>]..
FROM <表名或视图名> [,<表名或视图名>]
[WHERE<条件表达式>]
[GROUPBY<列名1>[HAVING<条件表达式>]]
[ORDER BY<列名2>[ASC|DESC]...]
- SOL查询中的子句顺序为SELECT、FROM、WHERE、GROUP BY、HAVING 和ORDER BY其中,SELECT、FROM 是必须的,HAVING条件子只能与GROUP BY搭配起来使用。
(1)SELECT子句对应的是关系代数中的投影运算,用来列出查询结果中的属性。其输出可以是列名表达式、集函数(AVG、COUNT、MAX、MIN、SUM),DISTINCT选项可以保证查询的结果集中不存在重复元组。
(2)FROM子句对应的是关系代数中的笛卡儿积,它列出的是表达式求值过程中需扫描的关系,即在FROM子句中出现多个基本表或视图时,系统首先执行笛卡儿积操作。
(3)WHERE子句对应的是关系代数中的选择谓词。WHERE 子句的条件表达式中可以使用的运算符如表所示。 - 简单查询:只涉及一张表。查询计算机系学生的学号和姓名。
select sno,sname from stu where depart='CS‘;
-
连接查询:查询涉及两个以上的表。查询选修了课程号为C1的学生号和学生姓名。
select sno,sname from SSC where S.sno=SCsno and SCcno='C1';
- 子查询:也称为嵌套查询,是指一个select-from-where查询块可以嵌入另一个查询块之中,SQL中允许多重嵌套。查询选修了课程号为C1的学生号和学生姓名。
select sno,sname from S where sno in (select sno from SC where cno=’ C1');
- 聚集函数:是以一个值的集合为输入,返回单个值的函数,SQL提供的聚集函数如下:
- 使用ANY和ALL谓词必须同时使用比较运算符用聚集函数实现子查询通常比直接用ALL或ANY查询效率更高,二者等价转换如下:
8.3.2 分组查询
● group by<列名1>[having <条件表达式>];
● group by 按某一列分组,一般只能select分组的列以及使用聚集函数
● 在group by子句后面加一个having子句,对分组设置过滤条件,可以使用聚集函数,注意:
● 空值在任何聚集操作中都会被忽视,如求和、求平均值和计数都没有影响,如count(*)是某个关系中所有元组数组之和,但count(A)却是A属性非空的元组个数之和。
● NULL值可以看做分组属性中的一个一般的值,例如,在select A,avg(B) from R中,当A的属性值为空时,就会统计A=NULL的所有元组中B的均值。
● 查找订单总金额小于2000的客户:
select customer, sum(orderPrice) from orders group by customer having sum(orderPrice) <2000;
8.3.3 其他操作
- 更名操作(as子句: ld name as new-name既可以出现在select子句中,也可以出现在from子句中select sname as 姓名, sage as 年 from S where SD=' CS';
- 字符串操作作对于字符串进行的最通用的操作时使用操作符like的模式匹配,使用两个特殊的字符描述:
%:匹配任意字符串
_:匹配任意一个字符模式是大小写敏感的,例如zhang%,mary_ 等。
select sname from S where saddress like '%张江%'; - 集合操作:在关系代数中用集合的并、交、差来组合关系,SQL提供了对应的操作,但是查询的结果必须具有相同的属性和类型列表。保留字union、intersect、 except分别对应并、交、差;
- 查询选修了180101号或180102号课程或二者都选修了的学生学号、课程号和成绩。
(SELECT学号课程号,成绩 FROM学习WHERE 课程号=180101)UNION
(SELECT学号课程号成绩 FROM学习WHERE 课程号=180102)
● UNION运算自动去除重复。如果想保留所有的重复,则必须用UNION ALL代替UNION,目查询结果中出现的重复元组数等于两个集合中出现的重复元组数的和。 - 查询同时选修了180101和180102号课程的学生学号、课程号和成绩。
(SELECT学号,课程号,成绩 FROM学习 WHERE 课程号=180101) INTERSECT
(SELECT学号课程号,成绩 FROM学习 WHERE 课程号=180102)
● INTERSECT运算自动去除重复,如果想保留所有的重复,必须用INTERSECT ALL代替● INTERSECT结果中出现的重复元组数等于两集合出现的重复元组数里较少的那个。 - 查询选修了180101号课程的学生中没有选修180102号课程的学生学号、课程号和成绩(SELECT学号课程号,成绩FROM学习WHERE课程号=180101)EXCEPT
(SELECT学号课程号,成绩 FROM学习WHERE 课程号=180102)
● EXCEPT运算自动去除重复,如果想保留所有的重复,必须用EXCEPT ALL代替EXCEPT,结果中出现的重复元组数等于两集合出现的重复元组数之差(前提是差是正值)
SQL对视图更新必须遵循以下规则:
(1)从多个基本表通过连结操作导出的视图不允许更新。
(2)对使用了分组、集函数操作的视图则不允许进行更新操作。
(3)如果视图是从单个基本表通过投影、选取操作导出的则允许进行更新操作,且语法同基本表 。
- 和过程定义不同的是Create view子句会在数据库中建立视图定义,该视图定义会一直保存,直到执行drop view 命令。但是,with子句提供了定义一个临时视图的方法,该定义只对with子句出现的那条查询有效。
- 插入insert
INSERTINTO 表名称 VALUES(值1值2,....)INSERTINTO table name(列1,列2...) VALUES (值1, 值2....)INSERT INTO Persons VALUES (GatesBill,Xuanwumen 10Beijing)INSERT INTO Persons (LastName, Address) VALUES (WilsonChamps-Elysees’) - 删除delete
DELETE FROM 表名称WHERE 列名称=值DELETE FROM Person WHERE LastName=Wilson' - 更新update
UPDATE 表名称SET 列名称=新值WHERE列名称=某值UPDATE Person SET FirstName =Fred' WHERE LastName = Wilson'
8.3.4 约束
- 主键约束primary key
- 完整性约束条件作用的对象有关系、元组和列
- 完整性控制具有的功能:定义功能、检测功能和处理功能。
- 检查是否违背完整性约束的时机有两种: 在一条语句执行完后立即检查称为立即执行约束;需要延到整个事务执行完后再检查称为延迟执行约束。
- 实体完整性:关系中只能由一个主键,声明主键有两种方法;
- 属性类型后加primary key 保留字;
- 在属性列表的最后增加一行primary key(属性或属性组)
外键约束foreign key
参照完整性定义格式:
foreign key(属性名)references 表名(属性)[on delete cascade set nullj;
references指明外键对应于哪个表的主键;
on delete cascade指明删除被参照关系的元组时,同时删除参照关系中的元组:
set null表示空值。
属性值上的约束,属性值上的约束通过下面关键字进行
not null:不允许空值
unique:唯一值
check:属性值要满足指定条件
create table students (sno char(8)not null unique,
sname char(10),
sage int,
sdept char(20),
primary key(sno),
foreign key(sdept) references D(dept),
check(sage >=15 and sage <= 22))
8.4 数据授权
8.4.1 授权grant
GRANT<权限>[<权限>]... [ON<对象类型><对象名>)TO<用户>[,<用户]>]...[WITH GRANT OPTION]
- 若指定了WITH GRANT OPTION子句,那么获得了权限的用户还可以将权限赋给其他用户: 接受权限的用户可以是单个或多个具体的用户,PUBLIC参数可将权限赋给全体用户。不同类型的操作对象有不同的操作权限,常见的操作权限如表所示。
grant all privileges on table S,PJ to user1, user2;
grant insert on table S to user1 with grant option;
8.4.2 收回权限revoke
REVOKE<权限>[,<权限>]... [ON<对象类型><对象名>]FROM<用户>[,<用户]>]... ;
revoke all privileges on table S,PJ from user1,user2;revoke select on table S from user1;
8.5 触发器
- 触发器和存储过程
● 触发器trigger是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发。
● 触发器经常用于加强数据的完整性约束和业务规则等;
● 触发器与存储过程的唯一区别是触发器不能执行execute语句调用,而是在用户执行transact-SQl语句时自动触发执行。
● 存储过程:是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。 - 触发器为数据库对象,当创建一个触发器时必须指定:
(1)名称;
(2)在其上定义触发器的表;
(3)触发器将何时激发;
(4)指明触发器执行时应做的动作。 - 触发动作实际上是一系列SQL语句,可以有两种方式:
(1)对被事件影响的每一行(FOR EACH ROW)-每一元组执行触发过程,称为行级触发器。(2)对整个事件只执行一次触发过程(FOREACHSTATEMENT),称为语级触发器。该方式是触发器的默认方式。 - 触发器的定义包括两个方面:指明触发器的触发事件,指明触发器的执行动作。
创建触发器:
(1)BEFORE:指示DBMS在执行触发语之前激发触发器
(2)AFTER:指示DBMS在执行触发语之后激发触发器。
(3)DELETE:每当一个DELETE语从表中删除一行时激发触发器。
(4)INSERT:每当一个时SERT 语句向表中插入一行时激发触发器
(5)UPDATE:每当UPDATE 语修改由OF子指定的列值时,激发触发器。如果忽略OF子,每当UDPATE 语修改表的任何列值时DBMS都将激发触发器
(6)REFERENCING<临时视图名>:指定临时视图的别名。在触发器运行过程中,系统会生成两个临时视图,分别存放被更新值 (旧值)和更新后的值(新值》。对于行级触发器,默认临时视图名分别是OLD 和NEW (oracle,在MS中,为Deleted,Inserted) ;对于语句级触发器,默认临时视图名分别是OLD-TABLE和NEW-TABLE。一旦触发器运行结束,临时视图就不在。
(7)WHEN<触发条件>:指定触发器的触发条件。当满足触发条件时,DBMS才激发触发器。触发条件中必须包含临时视图名,不包含查询。
CREATE TRIGGER<触发器名>LBEFORE | AFTER)([DELETE | INSERT | UPDATEOF [列名清单]])ON表名
[REFERENCING<临时视图名>][WHEN<触发条件>]
BEGIN
<触发动作>
END[触发器名]
【修改触发器】
ALTER TRIGGER<触发器名> [(BEFORE | AFTER]([DELETE | INSERTIUPDATEOF[列名清单]])
ON表名 | 视图名
AS
BEGIN
要执行的SQL语句
END
【删除触发器】
drop trigger trigger name
8.6 嵌入式SQL
- 将SQL语言嵌入到高级程序设计语言中使用
1.区分主语言语句与SQL 语句:
● 为了区分主语言语句与SQL 语句,需要在所有的SQl语句前加前缀EXEC SQL,而SQL的结束标志随主语言的不同而不同
● 例如,PL/1和C语言的引用格式为: EXEC SQLSQL 语句>;
● 又如,COBOL语言的引用格式为: EXEC SQL<SQL语句>END-EXEC。
2.主语言工作单元与数据库工作单元通信:
1)SQL 通信区SQL通信区向主语言传递SQL 语句执行的状态信息使主语言能够根据此信息控制程序流程。
2)主变量 - 主变量也称共享变量。主语言向SQL语句提供参数主要通过主变量,主变量由主语言的程序定义,并用SQL的DECLARE语句说明。例如在C语言中可用如下形式说明主变量
- 【游标】
一条SQL 语句可产生或处理多条记录。而主语言是面向记录的,一组主变SQL 语言是面向集合的量一次只能放一条记录,所以,引入游标,i通过移动游标指针来决定获取哪一条记录。与游标相关的SQL语句有四条:
(1)定义游标,格式如下
EXEC SOL DECLARE <游标名> CURSOR FOR
<SELECT语句>
END EXEC
这是一条说明性语句,定义中的 SELECT 语句并不立即执行。
(2) 打开游标,格式如下:
EXEC SQL OPEN <游标名> END EXEC
该语句执行游标定义中的 SELECT 语句,同时游标处于活动状况。游标是一个指针,此时指向查询结里的第一行之前。
(3)推进游标,格式如下
EXEC SQLFETCH FROM<游标名>INTO<变量表>ENDEXEC该语句使用时,游标推进一行,并把游标指向的行(称为当前行)中的值取出,送到共享变量中。变量表由用逗号分开的共享变量组成。该语句常置于宿主语言程序的循环结构中。
(4)关闭游标,格式如下:EXEC SQLCLOSE<游标名>END EXEC该语句关闭游标,使它不再和查询结果相联系。关闭了的游标,可以再次打开,与新的查询结果相联系。