SQL概述
SQL的特点
SQL集数据查询、数据操纵、数据定义和 数据控制功能于一体,其主要特点包含以下几部分:
1、功能统一
SQL集数据定义语言、数据操纵语言、数据控制语言的功能于一体,语言风格统一,可以独立完成数据库生命周期内的全部活动。
特别是用户在数据库系统投入运行后还可以根据需要随时地、逐步地修改模式,并不影响数据库的运行。
2、高度非工程话
只要提出“做什么”而无需之命“怎么做”,因此无需了解存取路径。存取路径的选择以及SQL的操作过程由系统自动完成。
3、面向集合的操作方式
非关系数据型采用的是面向记录的操作方式,操作对象是一条记录。而SQL采用集合操作方式,不仅操作对象、查找结果可以是元组的集合,而且一次插入、删除、更新操作的对象也可以是元组的集合。
4、以同一种语言结构提供多种使用方式
SQL既是独立的语言,又是嵌入式语言。作为独立的语言,它能够独立的用于联机交互的使用方式,用户可以在终端键盘上直接键入SQL命令对数据库进行操作;作为嵌入式语言,SQL语句能够嵌入到高级语言)(例如C、C++、Java)程序中,供程序员设计程序时使用。
5、语言简洁、易学易用
学生课程数据库
本章以学生-课程数据库为例来讲解SQL的数据定义,数据操纵、数据查询和数据控制语句。
为此,首先要定义一个学生-课程模式S-T,学生课程数据库中包含以下三个表:
学生表:Student(Sno,Sname,Ssex,Sage,Sdept)
课程表:Course(Cno,Cname,Cpno,Ccredit)
学生选课表:SC(Sno,Cno,Grade)
各个表中的数据:
学号 Sno |
姓名 Sname |
性别 Ssex |
年龄 Sage |
所在系 Sdept |
2017001 | 杜霄霖 | 女 | 22 | 软件工程 |
2017002 | 王磊 | 男 | 22 | 软件工程 |
2017003 | 王嘟嘟 | 男 | 21 | 电子商务 |
2017004 | 都蕾蕾 | 女 | 20 | 计算机科学 |
课程号 Cno |
课程名 Cname |
先修课 Cpno |
学分 Ccredit |
1 | 数据库 | 5 | 4 |
2 | 数学 | 2 | |
3 | 信息系统 | 1 | 4 |
4 | 操作系统 | 6 | 3 |
5 | 数据结构 | 7 | 4 |
6 | 数据处理 | 2 | |
7 | PASCAL语言 | 6 | 4 |
学号 Sno |
课程号 Cno |
成绩 Grade |
2017001 | 1 | 92 |
2017001 | 2 | 85 |
2017001 | 3 | 88 |
2017002 | 2 | 90 |
2017002 | 3 | 80 |
数据定义
关系数据库支持三级模式结构,其模式、外模式和内模式种的基本对象有模式、表、视图、和索引等。因此SQL的数据定义功能包括模式定义、表定义、视图和索引定义。
一个关系数据库管理系统的实例种可以建立多个数据库,一个数据库中可以建立多个模式,一个模式下通常包括多个表、视图和索引等数据库对象。
模式的定义与删除
1、定义模式
(定义了一个命名空间,架构)
在SQL中,模式定义的语句如下: create schema <模式名> authorization <用户名>
如果没有指定<模式名>,那么<模式名>隐含为<用户名>
要创建模式,调用该命令的用户必须拥有数据库管理员的权限,或者获得了数据库管理员授予的 create schema 的权限。
例一:为用户 wang 定义一个学生-课程模式 S-T
crate schema “S-T” authorization wang;
定义模式实际上定义了一个命名空间,在这个空间中可以进一步定义该模式包含的数据库对象,例如基本表、视图、索引等。
2、删除模式
SQL中,删除模式的语句如下:drop schema <模式名> <cascade|restrict>
其中cascade和restrict 两者必选其一,选择了cascade(级联),表示在删除模式的同时把该模式中部的所有数据库对象全部删除;选择了restrict (限制)表示如果该模式中已经定义了下属的数据库对象,则拒绝该删除语句的执行。
基本表的定义、删除与修改
1、定义基本表
创建了一个模式就建立的一个数据库命名空间,一个框架。在这个命名空间中首秀按要定义的激素hi该模式包含的数据库基本表。
SQL语言中使用 crate table语句定义基本表,其基本格式如下:
crate table <表名> (
<列名> <数据类型> [ 列级完整性约束条件 ]
[ ,<列名> <数据类型> [ 列级完整性约束条件 ]]
......
[ ,< 表级完整性约束条件 > ]
);
建表的同时通常还可以定义与该表有关的完整性约束条件,这些完整性约束条件被存入系统的数据库字典中,当用户操作表中的数据时又关系数据库管理系统自动检查该操作是否违背这些完整性约束条件。如果完整性约束条件涉及该表的多个属性列,则必须定义在表级上,否则既可以定义在列级也可以定义在表级。
例:建立一个学生表 Student
crate table Student
(
Sno char(9) primary key, 列级完整性约束条件,Sno是主码
Sname char(20) unique, Sname取唯一值
Ssex char(2),
Sage smallint,
Sdept char(20)
constraint ck_age check (sage>0) 表级约束条件,约束起名为ck-age,约束年龄大于20
);
例:建立一个课程表Course
crate table Course
(
Cno char (4) primary key, 列级完整性约束条件,Cno是主码
Cname char(40) not null , 列级完整性约束条件,Cname不能取空值
Cpno char(4), Cpno的含义是先修课
Ccredit smallint
foreign key(Cpno) references Course (Cno)
表级完整性约束条件,Cpno是外码,被参照表是Course,被参照列是Cno
);
本例说明参照表和被参照表可以是同一个表;被参照表一定是被声明过的,参照的列必须是表的主码。
2、修改基本表
随着应用环境和应用需求的变化,有时需要修改已建好的基本表。SQL语言用 alter table语句修改基本表,其一般格式为:
alter table <表名>
[ add [ column] <新列名> <数据类型> [ 完整性约束 ] ] //添加列
[ add <表级完整性约束> ] //添加表级完整性约束
[ drop [ column ] <列名> [ cascade | restrict] ] //删除列
[ drop constraint <完整性约束名> [ cascade | restrict] ] //删除约束
[ alter column <列名> <数据类型> ] ; //更改数据类型
例:向学生表(Student)中插入入学时间列(Sentrance),其数据类型为日期型
alter table Student add Sentrance date;
3、删除基本表
当某个基本表不再需要时,可以使用 drop table语句删除它。其一般格式为:
drop table <表名> [ cascade | restrict ];
若选择restrict,则表的删除是有限制条件的。想要删除的基本表不能被其他表的约束所引用(如check,foreign key等约束),不能有视图,不能有触发器,不能有存储过程或函数等。如果存在这些依赖该表的对象,则此表不能被删除。
若选择cascade,则该表的删除没有限制条件。删除基本表的同时,相关的依赖对象,例如视图,都将被一起删除。
索引的建立与删除
当表的数据量比较大时,查询操作比较耗时。建立索引是加快查询速度的有效手段。数据库索引类类似于图书后面的索引,能快速定位到需要查询的内容。
1、建立索引
在SQL语言中,建立索引使用create index语句,其一般格式为:
create [ unique ] [ clustered ] index <索引名>
on <表名>(<列名> [ <次序>] [ ,<列名> [ <次序>] ] ...);
其中表名是要建立基本表的名字。索引可以建立在该表的一列或者多列上,各列名之间用逗号分割。每个列名后面还可以用次序指定索引列的排列次序,可选ASC(升序)或DESC(降序),默认值为ASC。
unique表明此索引的每一个索引值只对应唯一的数据记录。
cluster表示要建立的索引是聚簇索引。
例:为学生表(Student)按学号升序建立唯一索引
crate unique index Stusno on Student(Sno);
2、修改索引
对于已经建立的索引,如果需要对其重新命名,可以使用alter index语句。其一般格式为:
alter index <旧索引名> rename to <新索引名>
3、删除索引
在SQL中,删除索引使用drop index语句,其一般格式为:
drop index <索引名>
数据字典
数据字典数关系数据管理系统内一组系统表,它记录了数据库中所有的定义信息,包括了关系模式定义、视图定义、索引定义、完整性约束定义、各类用户对数据库的操作权限、统计信息等。关系数据库管理系统在执行SQL的数据定义语句时,实际上就是更新数据字典的相应信息。在进行查询优化和查询处理时,数据字典中的信息时其重要依据。
数据查询
数据查询是数据库的核心操作,SQL提供了select语句进行数据查询,该语句具有灵活的使用方式和丰富的功能。其一般格式为:
select [ all | distinct ] <目标列表达式> [,<目标列表达式>]...
from <表或视图名>[ ,<表或视图名> ...] |(select 语句)[as] <别名>
[ where <条件表达式>]
[ group by <列名1> [havinng <条件表达式> ] ]
[ order by <列名2> [ asc | desc ] ]
整个select语句的含义是,根据where子句的条件表达式从from子句指定的基本表、视图或派生表中找出满足条件的元组,再按照select子句中的目标列表达式选出元组中的属性的值形成新的表。
如果有 group by子句,则将结果按照 <列名1>的值进行分组,该属性列值相等的元组为一个组。如果group by子句带having短语,则只有满足条件的组才能输出。
如果有order by子句,则结果还要按<列名2>的值升序或者降序。
单表查询
单表查询是指仅涉及一个表的查询。
1、选中表中的若干列
(1)查询指定列
在很多情况下,用户只对表中的一部分属性感兴趣,这是可以通过select子句在<目标列表达式>中指出要查询的属性列。
例:在学生关系表中查询全体学生的学号和姓名
select Sno,Sname form Student;
例:查询全体学生的姓名、学号、所在系
select Sname,Sno,Sdept form Student;
<目标列表达式>中各个列的先后顺序可以与表中的顺序不一致,用户可以根据应用需要改变列的显示顺序。
(2)查询全部列
将表中的全部属性列都选出来有两种办法,一种是select关键字后列出所有的列名;如果列显示顺序与其在基本表中的顺序相同,也可以简单的将<目标列表达式>指定为*
例:查询全体学生的全部记录:
select * from Student;
(3)查询经过计算的值
select子句<目标列表达式>不仅可以是表中的属性列,也可以是表达式。
例:查询全体学生的姓名及出生年份
select Sname,2021-Sage from Student;
可以使用as对列重新命名
select Sname,2021-Sage as year of birth from Student;
2、选择表中若干元组
(1)消除取值重复的行
两个本来并不完全相同的元组投影在指定的某些列上后,可能会变成相同的行,可以使用distinct消除它们。
例:
Sno | Sname | Ssex | Sage | Sdept |
2017001 | 张三 | 男 | 21 | 软件工程 |
2017002 | 李四 | 女 | 22 | 软件工程 |
2017003 | 王五 | 女 | 22 | 电子商务 |
2017004 | 赵六 | 男 | 23 | 计算机科学 |
查询计算机学院都有哪些专业的专业:
select sdept from Student; 结果为:
Sdept |
软件工程 |
软件工程 |
电子商务 |
计算机科学 |
该查询结果包含了重复的行,如果想去掉重复的行,必须指定distinct;
select distinct Sdept from Student;
则执行结果为:
Sdept |
软件工程 |
电子商务 |
计算机科学 |
如果没有指定distinct关键词,则默认为all,即保留结果表中取值重复的行。
(2)查询满足条件的元组
查询满足指定条件的元组可以通过where子句实现。where子句常用的查询条件:
查询条件 | 谓词 |
比较 | =,>,<,>=,<=,!=,<>,!>,!<;not加上述运算运算符 |
确定范围 | between and,not between and |
确定集合 | in,not in |
字符匹配 | like ,not like |
空值 | is null ,is not null |
多重条件(逻辑运算) | and,or,not |
比较大小:
查询所有年龄在20岁以下的学生姓名及其年龄。
select Sname,Sage from student where sage<20;
查询考试成绩不及格的学生的学号。
select Sno distinct Sno from SC where Grade<60;
确定范围:
between...and...和 not between ...and ...可以用来查找属性值在(或不在)指定范围内的元组,其中 between后的是范围的下限(低值)and 后的是上限(高值)
例:查询年龄在20~23岁(包括20岁和23岁)之间学生的姓名、年龄。
select Sname ,Sage from Student where Sage between 20 and 23;(包含边界)
确定集合:
谓词in用来查找属性值属于指定集合的元组。
查询软件工程、电子商务、计算机科学专业的学生的姓名和性别:
select Sname,Ssex from Student where Sdept in(‘软件工程’,‘电子商务’,‘计算机科学’);
与in 相对的是not in 用于查找属性值不属于指定集合的元组。
字符匹配:
谓词like可以用来进行字符匹配。其一般语法格式如下:
[ not ] like ‘<匹配串>’ [ escape ‘<换码字符>’]
其含义是查找指定列的属性值与<匹配串>相匹配的元组。<匹配串>可以是一个完整的字符串,页可以含有通配符%和_。 其中:
%(百分号)代表任意长度(长度可以为0)的字符串。例如a%b表示以a开头,以b结尾的任意长度的字符串。
_(下横线)代表任意单个字符。例如a_b表示以a开头,以b结尾的长度为3的任意字符串。
例:查询所有“杜”姓的学生的姓名、学号和性别。
select Sname,Sno,Ssex from Student where Sname like ‘杜%’;
例:查询名字中第二个字为“霄”的学生的姓名。
select Sname from Student where Sname like ‘_霄%’;
如果用户要查询的字符串本身就含有通配符 % 或 _,这时就要使用escape‘<换码字符>’短语对通配符进行转移了。
例:查询 DB_Design 课程的课程号和学分
select Cno,Ccredit from Course where Cname like ‘DB\_Design ’ escape '\';
escape '\'表示‘\‘为换码字符。这样匹配串紧跟在’\‘后面的字符’_‘不再具有通配符的含义。
涉及空值的查询:
某些学生选修课后没有参加考试,所有有选课记录,没有考试成绩,缺少考试成绩的学生的学号和相应的课程号:
select Sno,Cno from SC where Grade is null;
这里的is不能用”=“代替。
3、order by子句
用户可以用order by子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排序,默认为升序。
例:查询学修了3号课程的学生的学号及其成绩,查询结果按分数的降序排列。
Select Sno,Grade form SC where Cno='3' order by Grade Desc;
对于空值,排序时显示的次序由具体系统实现来决定。当根据多个属性列排列时,先根据第一个属性列排序,第一个属性列的值相同则依据第二个属性列的值排序。
4、聚集函数
为了进一步方便用户,增强检索功能,SQL提供了许多聚集函数。
count(*) | 统计元组的个数 |
count( [ distinct | all ] <列名>) | 统计一列中值的个数 |
sum( [ distinct | all ] <列名>) | 计算一列的值的和(此列必须是数值型) |
avg( [ distinct | all ] <列名>) | 计算一列的平均值(此列必须是数值型) |
max( [ distinct | all ] <列名>) | 求一列值中的最大值 |
min( [ distinct | all ] <列名>) | 求一列值中的最小值 |
如果指定distinct 短语,则表示在计算时要取消指定列中的重复值。如不指定distinct或者all短语,则不取消重复值。(all为默认值)。
例:查询学生的总人数:
select count(*) from Student;
例:查询选修了课程的学生的人数:
select count (distinct sno) from SC;//有的学生选择了多门课程,表中会有选修每门课程的记录。
例:查询选秀1号课程的学生的平均成绩:
select avg(Grade)as 平均成绩 from SC where Cno=’1‘;
当聚集函数遇到空值时,除count(*)外,都跳过空值而只处理非空值。注意:where 子句中是不能使用聚集函数作为条件表达式的,聚集函数只能用于select子句和group by 中的having子句。
5、group by子句
group by子句将查询结果按照某一列或者多列的值进行分组,值相等的为一组。分组后聚集函数将作用于每一个组 ,即每一个组都有一个函数值。
例:求各个课程号及相应的选课人数:
select Cno,count(Sno) from SC group by Cno;
此时select函数中只能出现分组属性和聚集函数;group by后面必须是唯一的分组属性。如果分组后还要求按一定的条件对这些分组进行筛选,最终只能输出满足指定条件的组,则可以使用having短语指定筛选条件。
例:查询选修了三门以上课程的学生的学号:
Select Sno form SC group by Sno having count(*)>3;
这里先用group by子句按照Sno进行分组,再用聚集函数count 对每一组计数;having 短语给定了选择组的条件,只有满足条件的组才会被筛选出来。
where子句与having子句的区别在于作用的对象不同。where子句作用于基本表或者视图,从中选择满足条件的元组。having短语作用于组,从中选出满足条件的组。
例:查询平均成绩大于90分的学生的学号和平均成绩。
select Sno,avg(Grade) from SC group by (Sno) having avg(Grade)>90;
where子句中是不能用聚集函数作为条件表达式。
连接查询
前面的查询都是针对一个表进行的。若一个查询同时涉及两个以上的表,则称之为连接查询。
1、等值连接与非等值连接
例:查询每个学生及其选课的情况
学生情况存放在Student表中,学生的选课情况存放在SC表中,所以本查询实际上涉及Student和SC两个表。这两个表之间的联系时通过Sno实现的。
select Student.*,SC.* from student,SC where student.Sno=SC.Sno;
student.Sno | Sname | Ssex | Sage | Sdept | SC.Sno | Cno | Grade |
2017001 | 杜霄霖 | 女 | 22 | 软件工程 | 2017001 | 1 | 92 |
2017001 | 杜霄霖 | 女 | 22 | 软件工程 | 2017001 | 2 | 85 |
2017001 | 杜霄霖 | 女 | 22 | 软件工程 | 2017001 | 3 | 88 |
2017002 | 王磊 | 男 | 22 | 软件工程 | 2017002 | 2 | 90 |
2017002 | 王磊 | 男 | 22 | 软件工程 | 2017002 | 3 | 80 |
本例中,select子句与where子句中的属性名前都加上了表名前缀,这是为了避免混淆,如果属性名在参加连接的各表中是一致的,则可省略表名前缀。
关系数据库管理系统执行练级操作的一种可能过程是:首先在Student中 第一个元组,然后从头开始扫描SC表,逐一查找与Student第一个元组的Sno相等的SC 的元组,然后找到后将Student中的第一个元组与该元组拼接起来,形成表中的一个元组,SC全部查找完后,再找Student中的第二个元组,然后再从头开始扫描SC,逐一查找满足连接条件的元组,找到后就将Student中的第二个元组与该元组拼接起来,形成结果表中的一个元组。重复上述操作,直到Student中的全部元组都处理完毕为止。这就是嵌套玄幻连接算法的基本思想。
如果SC表的Sno上建立了索引的话,就不用每次全表扫描SC表了,而是根据Sno值通过索引找到相应的SC'元组。用索引拆线呢SC中满足条件的元组一般比全表扫面快。
若等值连接中把目标列重复的属性列去掉为自然连接。
例:用自然连接完成查询每个学生及其选课的情况:
select Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
from Student,SC
where Student.Sno=Sc,Sno;
本例中,由于Sname,Ssex,Sage,Sdept,Cno,Grade属性列在Student表和SC表中是唯一的,引用时可以去掉表名前缀;而Sno在两个表都出现了,所以要加上表明前缀。
一条SQL语句可以同时完成选择和连接查询,这时where子句是由连接谓词和选择谓词组成的复合条件。
例:查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
select Student.Sno,Sname
from Student,SC
where Student.Sno=Sc.Sno and SC.Cno='2' and SC.Grade>'90';
该查询的一种优化(高效)的执行过程是,先从SC中挑出Cno=’2‘并且Grade>90的元组形成一个中间关系,再和Student中满足连接条件的元组进行连接得到最终的连接关系。
2、自身连接
连接操作不仅可以在两个表之间进行,也可以是一个表与它自己进行连接,称为表的自身连接。
嵌套查询
在SQL语言中,一个 select-from-where 语句称为一个查询块。将一个查询块嵌套在另一个查询块的where子句或者having短语的条件中称为嵌套查询。
SQL语句允许多层嵌套查询,即一个子查询还可以嵌套其他子查询。需要特别指出的是,子查询的select语句不能使用order by子句;order by子句只能对最终的查询结果进行排序。
1、带有 IN 谓词的子查询
在嵌套查询中,子查询的结果往往是一个集合,所以谓词 IN 是嵌套查询中最经常使用的谓词。
例:查询与”杜霄霖“在一个专业学习的学生的学号和姓名。
select Sno,Sname
from Student
where Sdept in
(
select Sdept from Student where Sname=’杜霄霖‘
);
本例中,子查询的查询条件不依赖于父查询,称为不相关查询。
例:查询选修了课程名为"信息系统"的学生的学号和姓名
本查询涉及学号、姓名和课程名三个属性。学号和姓名存放在Student表中,课程名存放在Course表中,但是Student和Course 两个表之间没有直接的联系,必须通过SC建立它们两者之间的联系,所以本查询涉及三个关系。
select Sno ,Sname
from Student
where Sno in
(
select Sno
from SC
where Cno in
(
select Cno
from Course
where Cname=”信息系统“
)
);
第一步:在Course关系中找到”信息系统”的课程号,结果是3
第二步:然后在SC关系中找出选修了3号课程的学生的学号
第三步:最后在Student关系中取出Sno和Sname
2、带有比较运算符的子查询
带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户能确切知道内层查询返回的是单个值时,可以用比较运算符。
例:找出每个学生超过他自己选修课平均成绩的课程号:
select Sno,Cno
from SC x
where Grade >=(select avg(Grade)
from SC y
where x.Sno=y.Sno
);
内层查询时求一个学生所有选修课的平均成绩的,至于哪个学生的平均成绩要看参数x.Sno的值,而该值是与父查询相关的,因此这类查询称为相关子查询。
3、带有any(some)或all谓词的子查询
子查询返回单值时可以用比较运算,但返回多值时要用any(有的系统用some)或all谓词修饰符。而使用any或all谓词时必须同时使用比较运算符。
>any | 大于子查询结果中的某个值 |
>all | 大于子查询结果的中所有值 |
<any | 小于子查询结果中的某个值 |
<all | 小于子查询结果中的所有值 |
>=any | 大于等于子查询结果中的某个值 |
>=all | 大于等于子查询结果中的所有值 |
<=any | 小于等于子查询结果中的某个值 |
<=all | 小于等于子查询结果中的所有值 |
=any | 等于子查询结果中的某个值 |
=all | 等于子查询结果中的所有值(通常没有实际意义) |
!=(或<>)any | 不等于子查询结果中的某个值 |
!=(或<>)all | 不等于子查询结果中的任何一个值 |
例:查询非计算机科学专业中比计算机科学专业中任意一个学生年龄小的学生的姓名和年龄。
select Sname,Sage
from Student
where Sage < any (select Sage
from Student
where Sdept='计算机科学'
)
and sdept != '计算机科学' ;
4、带有exisits谓词的子查询
exisits代表存在量词,带有exisits谓词的子查询不返回任何数据,只产生逻辑真值 “true”和逻辑假值“false”。
例:查询选修了1号课程的学生的姓名。
select Sname
from Student
where exisits ( select *
from SC
where Sno=Student.Sno and Cno='1'
);
本查询涉及Student和SC两个表,可以在Student中依次取每个元组的Sno值,用此值去检查SC表,若SC中存在这样的元组,其Sno的值等于Student.Sno的值,并且Cno=’1‘,则取此Student.Sname送入结果表。
使用存在量词exisits后,若内层查询结果为非空,则外层的where子句返回真值,否则返回假值。
集合查询
select 语句的查询结果是元组的集合,所以多个select 语句可进行集合操作。集合操作主要包括并操作 union、交操作 intersect和差操作 except。
注意:参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同。
[union 例]:查询计算机科学专业的学生及年龄不大于23岁的学生的信息。
本查询实际上时求计算机科学专业的所有学生与年龄不大于23岁的学生的并集。使用union将多个查询结果合并起来时。系统会自动去掉重复的元组,如果要保留重复元组则用union all操作符。
select * from Student where Sdept=’计算机科学‘
union
select * from Student where Sage<=23 ;
[intersect 例]:查询计算机科学专业中年龄不大于23岁的学生的信息
select * from Student where Sdept=’计算机科学‘
intersect
select * from Student where Sage <= '23' ;·
[except 例]:查询计算机科学专业中年龄大于23岁的学生的信息
使用差集表示,就是查询计算机专业的学生与年龄不大于23岁的学生的信息
select * from Student where Sdept=’计算机科学‘
except
select * from Student where Sage <=23 ;
数据更新
数据更新有三种操作:向表中添加若干行数据、修改表中的数据和删除表中的若干行数据。
插入数据
SQL的数据插入语句 insert 通常有两种形式,一种是插入一个元组,另一种是插入子查询结果。后者可以一次插入多个元组。
1、插入元组
插入元组的 insert 语句的格式为:
insert into <表名> [ (< 属性列1 > [ ,<属性列2> ] ...) ]
values ( <常量1> [ ,<常量2> ] ... ) ;
其功能是将新元组插入指定表中,其中新元组的属性列1 的值为常量1...,into 子句中没有出现的属性列,新元组在这些列上取空值。但必须注意的是,在表定义时说明了not null 的属性列不能取空值,否则会报错。
如果into子句中没有指明任何属性列名,则新插入的元组必须在每个属性列上均有值。
例:将一个新学生元组(学号:200705,姓名:王小杜,性别:男,所在系:电子商务,年龄:20岁)插入到学生表中:
insert
into Student (Sno,Sname,Ssex,Sdept,Sage)
values( '2017005' ,'王小杜' ,’男‘,’电子商务‘,20) ;
2、插入子查询结果
插入子查询结果的insert语句格式为:
insert
into <表名> [ (<属性列1> [ ,<属性列 2> ....]) ]
子查询;
修改数据
修改数据又称为更新操作,其语句的一般格式为
update <表名>
set <列名> =<表达式> [ ,<列名> =<表达式> ] ...
[ where <条件> ] ;
例:将所有学生的年龄增加一岁
update Student
set Sage=Sage+1 ;·
子查询也可以嵌套在update语句中,用以构造修改条件。
例:将软件工程专业全体学生的成绩置 0
update SC
set Grade=0
where Sno in ( select Sno
from Student
where Sdept=’软件工程‘
);
删除数据
删除数据的一般格式为:
delete
from <表名 >
[ where <条件> ]
例:删除学号为2017003的学生记录
delete from Student where Sno=’2017003‘ ;
视图
视图时从一个或几个基本表(或视图)导出的表。它与基本表不同,是一个虚表。数据库中只存放视图的定义,而不存放视图对应的数据,这些数据仍放在原来的基本表中。
视图一经定义,就可以跟基本表一样被查询、被删除。也可以在一个视图之上再定义新的视图,但是对新视图的(增、删、改)操作有一定的限制。
定义视图
1、建立视图
SQL语言用 create view 命令建立视图,其一般格式为:
create view <视图名> [ ( <列名> [ ,<列名> ]... ) ]
as <子查询>
[ with check option ]
其中子查询可以是任意的select子句,是视图数据的来源。
with check option 表示对视图进行 update、insert、delete 操作时要保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询语句中的条件表达式)
组成视图的属性列名或者全部省略或者全部指定,没有第三章并选择。如果省略了视图个各个属性列名,则隐含该视图由子查询中select子句目标列中的诸字段组成。但是在下列三种情况下必须明确的指定组成视图的所有列名:
(1)某个目标列不是单纯的属性名,而是聚集函数或表达式式
(2)多表连接时选出了几个同名列作为视图的字段
(3)需要在视图中为某个列启用新的更合适的名字
例:建立软件工程专业学生的视图
create view SG_Student
as
select Sno,Sname,Sage
from Student
where Sdept=’软件工程‘
关系数据库管理系统执行create view语句的结果只是把视图的定义存入数据字典,并不执行其中的select 语句。只是在对视图查询时,才按照视图的定义从基本表中将视图查出。
例:建立软件工程专业学生的视图,并要求进行修改和插入操作时仍需要保证该视图只有软件工程专业的学生。
create view SG_Student
as
select Sno,Sname,Sage
from Student
where Sdept=’软件工程‘
with check option;
由于在定义SG_Student 视图时加上了with check option 子句,以后对该视图进行插入、修改和删除操作时,关系数据库管理系统会自动加上 Sdept='软件工程' 的条件。
例:定义一个反应学生出生年份的视图
create view BT_S (Sno,Sname,Sbirth)
as
select Sno,Sname,2021-Sage
from Student;
视图中的出生年份时通过计算得到的。
2、删除视图
该语句格式为: drop view <视图名> [ cascade ] ;
视图删除后视图的定义将从数据字典中删除。如果视图还导出了其他视图,则使用cascade级联删除语句把该视图和由它导出的视图一起删除。
3、查询视图
视图定义后,用户就可以向=像对基本表一样对视图进行查询了。
关系数据库管理系统执行对视图的查询时,首先进行有效性检查,检查查询中涉及的表、视图是否存在。如果存在,则从数据字典中取出视图的定义,把定义中的子查询和用户的查询结合起来,转换成等价的对基本表的查询,然后再执行修正了的查询。这一转换过程称为视图消解 。
视图的作用
1、视图能够简化用户的操作
2、视图使用户能以多种角度看待同一数据
3、视图对重构数据库提供了一定程度上的逻辑独立性
4、视图能够对机密数据提供安全保护
5、适当利用视图可以更清晰的表达