数据库第三章

第三章:关系数据库标准语言SQL

注意:SQL(Oracle除外)一般不提供修改视图定义和索引定义的操作,需要先删除再重建

定义基本表:

CREATE TABLE<表名>
(<列名>数据类型> [<列级完整性约束条件>]
[,<列名><数据类型型>[列级完整性约束条件]]
[,<表级完整性约束条1>]);

列级完整性约束-涉及到该表的一个属性

  • NOT NULL:非空值约束
  • UNIQUE:唯一性(单值约束)约束
  • PRIMARY KEY:主码约束
  • DEFAULT 默认值默认(缺省)约束
  • Check<逻辑表达式)>核查约束,定义校验条件
  • NOT NULL:非空值约束
  • UNIQUE:唯一性(单值约束)约束
  • PRIMARY KEY:主码约束
  • DEFAULT 黑默认值>黑默认(缺省)约束
  • Check<逻辑表达式)>核查约束,定义校验条件

表级完整性约束-涉及到该表的一个或多个属性

  • UNIQUE(属性列列表):限定各列取值唯一
  • PRIMARY KEY 属性列列表):指定主码
  • FOREIGN KEY 属性列列表)REFERENCES 表名>[属性列列表)]
  • Check(s逻辑表达式>):检查约束
    PRIMARY KEY与UNIQUE的区别?
例:建立“学生”表Student,学号是主码,姓名取值唯一

CREATE TABLE Student
(Sno CHAR(9)PRIMARY KES,/*主码*/
Sname CHAR(20)UNIQUE,/*Sname取唯一值*/
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20));

修改基本表

ALTER TABLE<表名>
[ADD<新列名><数据类型>[完整性约束]]
[DROP<列名>|<完整性约束名>]
[ALTER COLUMN <列名><数据类型>];

例:向Student表增加入学时间”列,其数据类型为日期型

ALTER TABLE Students ADD S_entrance DATE;
不论基本表中原来是否已有数据,新增加的列一律为空值


将年龄的数据类型由字符型(假设原来的数据类型是字符型)改为整数
ALTER TABLE StudentALTER COLUMNSage INT;
注:修改原有的列定义有可能会破坏已有数据


增加课程名称必须取唯一值的约束条件
ALTER TABLE Course ADD UNIOUE(Cname);

例:直接删除属性列

ALTER TABLE Student Drop Sags;

删除基本表

DROP TABLE<表名>[RESTRICT | CASCADE];

  • RESTRICT:(受限)欲删除的基本表不能被其他表的约束所引用,如果存在依赖该表的对象(触发器,视图等),则此表不能被删除。
  • CASCADE:(级联)在删除基本表的同时,相关的依赖对象一起删除。

例:删除Student表

DROP TABLE Student CASCADE;
基本表定义被删除,数据被删除;表上建立的索引、视图、触发器等一般也将被删除。

删除索引

DROP INDEX <索引名>;
删除索引时,系统会从数据字典中删去有关该索引的描述。

例:删除Student表的Stusname索引

DROP INDEX Stusname;;

数据查询

单表查询

选择表中的若干列(投影)
查询指定列(相当于πA(R),A=A1,A2…An)

例;查询全体学生的学号与姓名

SELECT Sno,Sname
FROM Student;


查询全部列 :
在SELECT关键字后面列出所有列名按用户指定顺序显示。
将<目标列表达式>指定为* 按关系模式中的属性顺序显示。

例:查询全体学生的详细记录

SELECT Sno,Sname,Ssex,Sdept,Sage
FROM Student

SELECT *
FROM Student;


例:查全体学生的姓名及其出生年份

SELECT Sname,2011-Sage
FROM Studen;


例:查询全体学生的姓名、出生年份和所有系,要求用小写字母表示所有系名

SELECT Sname,‘Year of Birth:’,2004-Sage,ISLOWER(Sdept)
FROM Student;
列别名
SELECT Sname as NAME,'Year of Birth:'as BIRTH,
2011-Sage as BIRTHDAYLOWER(Sdept)as DEPARTMENT
FROM Student;

消除重复性:

指定DISTINCT关键词,去掉表中重复的行

SELECT DISTINCT SnO
FROM SC;
注意DISTINCT短语的作用范围是所有目标列
错误的写法 SELECT DISTINCT Cng DISTINCT Grade FROM SC;正确的写法SELECT DISTINCT Cno Grade FROM SC;SELECT 子句缺省情况是保留重复元组ALL)

例:查询选修了课程的学生学号。

SELECT Sno FROM SC;
等价于:
SELECT ALL Sno FROM SC;


WHERE子句常用的查询条件(相当于σF)

比较大小使用比较运算符或逻辑运算符NOT+比较运算符

例:查询计算机科学系全体学生的名单

SELECT Sname
FROM Student
WHERE Sdept=‘CS’;

例:查询所有年龄在20岁以下的学生姓名及其年龄

SELECT Sname,Sage
FROM Student
WHERE Sage<20;


确定范围BETWEEN,AND,NOT BETWEEN…AND…

例;查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄

SELECT Sname Sdept,Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23;

例:查询年龄不在20~23岁之间的学生姓名、系别和年龄

SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;


确定集合IN<值表>,NOT IN<值表>

例:查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别

SELECT Sname,Ssex
FROM Student
WHERE Sdept IN(IS"MA’,CS’);

例:查询既不是信息系、数学系,也不是计算机科学系的学生的姓名和性别

SELECT Sname,Ssex
FROM Student
WHERE Sdept NOT IN(‘ISMA’,‘CS’);


字符匹配[NOT] LIKE’<匹配串>’[ESCAPE‘<换码字符>’]
匹配串为固定字符串

例:查询学号为200215121的学生的详细情况。

SELECT *
FROM Student
WHERE Sno LIKE ‘200215121’;
等价于:
SELECT *
FROM Student
WHERE Sno=‘200215121’;


匹配串为含通配符的字符串

  • %:代表任意长度(可以是0)的字符串
  • _ :代表任意单个字符
  • 字符串本身就含有%或时,在%或之前加上转义符“\”要使用ESCAPE‘<换码字符>’将通配符转义为普通字符。如果‘\’要作为一个普通字符,用连续两个‘\’表示一个真正的\’。
例:查询以“DB_"开头,且倒数第3个字符为i的课程的详细情况。

SELECT*
FROM Course
WHERE Cname LIKE’DB_%i_ _‘ESCAPE’\’;
涉及空值的查询IS NULL或IS NOT NULL“IS”不能用“=”代替

例:查所有有成绩的学生学号和课程号

SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;


多重条件查询:AND和OR来联结多个查询条件,AND的优先级高于OR,可以用括号改变优先级,可用来现多种其他谓词。[NOT]IN INOT]BETWEEN…AND…

改写例:查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别

SELECT Sname,Ssex
FROM Student
WHERE Sdept IN(‘IS’,MA’,‘CS’);

可改写为:

SELECT Sname,Ssex
FROM Student
WHERE Sdept=‘IS’ OR Sdept=‘MA’ OR Sdept=‘CS’;


ORDER BY子句:对查询结果排序

可以按一个或多个属性列排序:

  • 升序:ASC;
  • 降序:DESC;
  • 缺省值为升序。
  • 当排序列含空值时:空值最大
  • ASC:排序列为空值的元组最后显示;
  • DESC:排序列为空值的元组最先显示。
例:查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列

SELECT Sname, Grade
FROM SC
WHERE Cno=‘3’
ORDER BY Grade DESC;

聚集函数:对查询结果集中的某列进行计算或统计。

  • 计数COUNT([DISTINCTIALL]*COUNT([DISTINCTIALL]列名>)
  • 计算总和SUM ([DISTINCT|ALL]<列名>)
  • 计算平均值AVG ([DISTINCT|ALL]<列名>)
  • 计算总和SUM ([DISTINCT|ALL]<列名>)
  • 计算平均值AVG ([DISTINCT|ALL]<列名>)
  • 最大值MAX ([DISTINCT|ALL]<列名>)
  • 最小值MIN ([DISTINCT|ALL]<列名>)

例:查询学生200215012选修课程的总学分数

SELECT SUM(Ccredit)
FROM SC,Course
WHERE Sno=‘200215012’ AND SC.Cno=Course.Cno;
注:除Count(*),都要跳过空值;Where子句不能使用聚集函数。


GROUPBY子句:对查询结果分组。

  • 用途细化聚集函数的作用对象
  • 未对查询结果分组,聚集函数将作用于整个查询结果
  • 对查询结果分组后,聚集函数将分别作用于每个组
  • 使用GROUPBY后:其SELECT子句的列名列表中只能出现分组属性和集函数。
  • 如果分组后还要按照条件对这些组进行筛选,可使用having短语指定筛选条件
例:查询选修了3门以上课程的学生学号

SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*)>3

例:查询有3门以上课程是90分以上学生的学号及(90分以上的)课程数

SELECT Sno,COUNT(*)
FROM SC
Where Grade >90
GROUP BY Sno
HAVING COUNT(*)>3;


**HAVING 短语与WHERE子句的区别 **
作用对象不同WHERE子句作用于基表或视图,从中选择满足条件的元组
HAVING短语作用于组,从中选择满足条件的组。

数据更新

插入数据

插入元组
INSERT
[INTO]<表名>[(<属性列1>[,<属性列2>,)]
VALUES(<常量1><常量2>],)

功能:将新元组插入指定表中;新元组的属性列1的值为常量1,属性列2的值为常量2.

  • INTO子句:属性列的顺序可与表定义中的顺序不一致,但须指定列名;没有指定属性列,表示要插入的是一条完整的元组;指定部分属性列,未指定的属性列取空值,具有NOTNULL的属性列除外。
  • VALUES子句:提供的值必须与INTO子句匹配,值的个数,值的类型。
例:将一个新学生元组(学号:200215128;姓名:陈冬;性别:男;所在系:IS;年龄:18岁)插入到Student表中

INSERT
INTO Student(Sno Sname,Ssex,Sdept,Sage)
VALUES(200215128:陈冬,男,IS’,18);

例:将学生张成民的信息插入到Student表中

INSERT
INTO Student
VALUES(‘200215126’,‘张成民’,‘男’,18,‘CS’);

例:插入一条选课记录(200215128,1)

INSERT INTO SC(SnaCno)
VALUES(‘200215128’,‘1’);
RDBMS将在新插入记录的Grade列上自动地赋空值。或者:
INSERT INTO SC VALUES(‘200215128’,‘1’,NULL);因为没有指出SC的属性名,在GRADE列上要明确给出空值插入子查询结果
Insert Into表名[(<属性列1>[,<属性列2)]
子查询(select等);

修改数据

UPDATE<表名
SET <列名>=<表达式[,<列名>=<表达式]。
[WHERE条件>];SET子句:指定修改方式,要修改的列,修改后取值:<表达式>。
WHERE子句:指定要修改的元组,,缺省表示要修改表中的所有元组。
功能:修改指定表中满足WHERE子句条件的元组。
修改某一个元组的值

例:将学生200215121的年龄改为22岁

UPDATE Student
SET Sage=22
WHERE Sno='200215121;


修改多个元组的值

例:将所有学生的年龄增加1岁

UPDATE Student
SET Sage=Sage+1;
子查询的修改语句子查询须放在比较运算符之后

例:将计算机科学系全体学生的成绩置零。

UPDATE SC
SET Grade=0
WHERE’CS’=
(SELETE Sdept
FROM Student
WHERE Student.Sno=SC.Sno);

删除数据

DELETE FROM<表名>
[WHERE条件>];

  • 功能:删除指定表中满足WHERE子句条件的元组。
  • WHERE子句:指定要删除的元组;缺省表示要删除表中的全部元组,表的定义仍在数据字典中。

删除某一个元组的值

例:删除学号为200215128的学生记录

DELETE FROM Student
WHERE Sno=‘200215128’;


删除多个元组的值

例:删除所有的学生选课记录

DELETE FROM SC;


带子查询的删除语句

例:删除计算机科学系所有学生的选课记录

DELETE FROM SC
WHERE’CS’=
(SELETE Sdept
FROM Student
WHERE Student.Sno=SC.Sno)

视图

特点:虚表,是从一个或几个基本表(或视图)导出的表;只存放视图的定义,不存放视图对应的数据;基表中的数据发生变化,从视图中查询出的数据也随之改变。
基于视图的操作:查询、删除、受限更新、定义基于该视图的新视图。

定义视图

建立视图
CREATE VIEW视图名[(<列名[,<列名],)]
AS<子查询>
[WITH CHECK OPTIO];
子查询:不允许含有ORDERBY子句和DISTINCT短语。
WITH CHECK OPTION:表示对视图进行UPDATE,INSERT和DELETE操作时要保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)。
组成视图的属性列名:全部省略或全部指定,但在下列三种情况下必须明确指定组成视图的所有列名:

  • 某个目标列不是单纯的属性名,而是聚集函数或列表达式;
  • 多表连接时选出了几个同名列作为视图的字段;
  • 需要在视图中为某个列启用新的名字。

RDBMS执行CREATE VIEW语句时只是把视图定义存入数据字典,并不执行其中的SELECT语句。在对视图查询时,按视图的定义从基本表中将数据查出。
行列子集视图:从单个基本表导出,只是去掉了基本表的某些行和某些列保留了主码

例:建立信息系学生的视图

CREATE VIEW IS_Student
AS
SELECT Sna Sname,Sage
FROM Student
WHERE Sdept=‘IS’
WITH CHECK OPTION;

例:建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生

CREATE VIEW IS_Student
AS
SELECT Sna Sname,Sage
FROM Student
WHERE Sdept=‘IS’
WITH CHECK OPTION;

加上了WITH CHECK OPTION子句。如果不是,则拒绝该插入操作。如果没有提供Sdept属性值,则自动定义Sdept为IS。


基于多个基表的视图

例:建立信息系选修了1号课程的学生视图

CREATE VIEW IS_S1(Sno Sname,Grade)
AS
SELECT Student.Sna,Sname,Grade
FROM Student,SC
WHERE Sdept=‘IS’ AND Student.Sno=SC.Sno AND SC.Cno='1;


基于视图的视图

例:建立信息系选修了1号课程且成绩在90分以上的学生的视图

CREATE VIEW IS_S2
AS
SELECT Sna,Sname,Grade
FROM IS_S1
WHERE Grade>=90;
由于视图中的数据不会实际存储,所以定义视图时可根据应用的需要,设置一些派生属性列或虚拟列,以便于查询和统计。
以SELECT*方式创建的视图可扩充性差,应尽可能避免。

例:删除视图BT_S:

DROP VIEW BT_S;删除视图IS_S1:拒绝执行
级联删除:DROP VIEW IS S1 CASCADE;


查询视图

查询视图与查询基本表相同,视图定义后,就可以像对待基本表一样对视图进行查询(SELECT)操作。
视图消解法(View Resolution)进行有效性检查,检查查询的表、视图等是否存在。如果存在,则从数据字典中取出视图的定义;转换成等价的对基本表的查询,把视图定义中的子查询与用户的查询结合起来;执行修正后的查询。

例:在信息系学生的视图中找出年龄小于20岁的学生

SELECT Sno,Sage
FROM IS_Student
WHERE Sage<20;
视图消解转换后的查询语句为:
SELECT Sno,Sage
FROM Student
WHERE Sdept=IS’AND Sage<20;

例:在S_G视图中查询平均成绩在90分以上的学生学号和平均成绩

SELECT *
FROM SG
WHERE Gavg>=90;
S_G视图的子查询定义:
CREATE VIEW S_G(Sno ,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;

更新视图

DBMS实现视图更新的方法:转换为对基本表的更新。视图消解法(View Resolution)。

对于视图元组的更新操作(INSERT、DELETE、UPDATA),有以下三条规则:
如果一个视图是从多个基本表使用联接操作导出的,那么不允许对这个视图执行更新操作。如果在导出视图的过程中,使用了分组和聚集函数操作,也不允许对这个视图执行更新操作。
行列子集视图可以执行更新操作。
在SQL2中,允许更新的视图在定义时,必须加上“WITH CHECK OPTION短语。DBMS在更新视图时会进行检查,防止用户通过视图对不属于视图范围内的基本表数据进行更新。

例:将信息系学生视图ISStudent中学号200215122的学生姓名为“刘辰”。

UPDATE IS_Student
SET Sname=‘刘辰’
WHERE Sno=‘200215122’;
转换后的语句:
UPDATE Student
SET Sname=‘刘辰’
WHERE Sno=‘200215122’ AND Sdept=‘IS’;

例:向信息系学生视图IS_S中插入一个新的学生记录:200215129,赵新,20岁

INSERT INTO IS_Student VALUES(‘200215129’,‘赵新’,20);
转换为对基本表的更新:
INSERT
INTO Student(Sno,Sname,Sage,Sdept)
VALUES(‘200215129’,‘赵新’,20);

例:丽除信息系学生视图IS_Student中学号为200215129的记录

DELETE FROM IS_Student
WHERE Sno=‘200215129’;
转换为对基本表的更新:
DELETE FROM Student WHERE Sno=‘200215129’ AND Sdept=‘IS’;

更新视图的限制

一些视图是不可更新的,因为对这些视图的更新不能唯一地有意义地转换成对相应基本表的更新。对其他类型视图的更新不同系统有不同限制:

  1. 若视图是由两个以上基本表导出的,则此视图不允许更新
  2. 若视图的字段来自字段表达式或常数,则不允许对此视图执行INSERT和UPDATE操作,但允许执行DELETE操作。
  3. 若视图的字段来自集函数,则此视图不允许更新。
  4. 若视图定义中含有GROUPBY子句,则此视图不允许更新。
  5. 若视图定义中含有DISTINCT短语,则此视图不允许更新。
  6. 若视图定义中有嵌套查询,并且内层查询的FROM子句中涉及的表也是导出该视图的基本表,则此视图不允许更新。
  7. 一个不允许更新的视图上定义的视图也不允许更新
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值