三、SQL语言
SQL语言:结构化查询语言的简称,是关系数据库的标准语言。SQL是一种通用的、功能极强的关系数据库语言,是对关系数据存取的标准接口,也是不同数据系统之间互相操作的基础。集数据查询、数据操作、数据定义和数据控制功能于一体。
数据查询:即根据相关条件从数据库中查找数据;关键字:select
数据定义:数据定义功能包括模式定义、表定义、视图定义和索引定义。关键字:Create、Drop、Alter
数据操作:即数据库的增删改查等操作。关键字:Insert、Updata、Delete
数据控制:用来授权或回收数据库的某种特权,并控制数据库操纵事务发生的时间及效果。关键字:GRANT、REVORK
SQL支持三级模式结构:视图 -> 外模式 基本表 -> 模式 存储文件 -> 内模式
下面以表为例,为大家展示一下,表的数据定义、数据操作、数据查询和数据控制。
(1)数据定义
数据库系统支持的数据类型有:
数据类型 | 含义 |
---|---|
char(n) | 长度为n的定长字符串 |
varchar(n) | 最大长度为n的变长字符串 |
INT | 长整数(也可以写作INTEGER) |
SMALLINT | 短整数 |
NUMERIC(p,d) | 定点数,由p位数字(不包括符号、小数点)组成,小数后面有d位数字 |
REAL | 取决于机器精度的浮点数 |
Double Precision | 取决与机器精度的双精度浮点数 |
FLOAT(n) | 浮点数,精度至少为n位数字 |
DATE | 日期,包含年、月、日,格式为YYYY-MM-DD |
TIME | 时间,包含一日的时、分、秒,格式为HH:MM:SS |
SQL数据定义语句操作的对象有:模式、表、视图和索引
操作对象 | 创建 | 删除 | 修改 |
---|---|---|---|
模式 | CREATE SCHEMA | DROP SCHEMA | |
表 | CREATE TABLE | DROP TABLE | ALTER TABLE |
视图 | CREATE VIEW | DROP VIEW | |
索引 | CREATE INDEX | DROP INDEX |
- 表定义
SQL创建表语句的一般格式为:
CREATE TABLE <表名>
(<列名> <数据类型> [<列级完整性约束>]
[,<列名> <数据类型> [<列级完整性约束>]] ...
[,<表级完整性约束>]);
其中<数据类型>可以是数据库系统支持的各种数据类型,包括长度和精度。[]内的内容是可选的。
列级完整性约束为针对单个列(本列)的完整性约束,包括PRIMARY KEY、REFERENCES表名(列名)、UNIQUE、NOT NULL等。
表级完整性约束可以是基于表中多列的约束,包括PRIMARY KEY(列名)、FOREIGN KEY REFERENCES 表名(列名)等。
【示例】
create table instructor2(
id char(5) not null,
name varchar(20) not null,
dept_name varchar(20) not null,
salary numeric(8,2),
primary key(id)
);
(2)数据操作
- 插入元组,语法如下:
insert into 关系名 values(每个属性对应的值);//关系名,即表名
【示例】
insert into instructor2 values(00001,'ai','math',2500.37);
insert into instructor2 values(00002,'la','math',3700.89);
insert into instructor2 values(00003,'bi','math',5400.45);
insert into instructor2 values(00004,'ma','english',1450.23);
insert into instructor2 values(00005,'ye','english',3421.34);
insert into instructor2 values(00006,'er','technology',10000.65);
- 删除所有元组,语法如下:
delete from <关系名>;//关系名,即表名
使用该语句删除所有元组后,关系和属性仍是存在,你可以继续对该关系进行插入元组操作。
- 删除关系,语法如下:
drop table <关系名> [RESTRICT | CASCADE];//关系名,即表名
使用该语句删除关系后,该关系就彻底被销毁了。
[]内的内容可选,若选择RESTRICT,则该表的删除是有限制条件的。欲删除的表不能被其他表的约束所引用(CHECK, FOREIGN KEY等约束),不能有视图,不能有触发器,不能有存储过程或函数等,如果存在这些依赖该表的对象,则此表不能被删除。
若选择CASCADE:则该表的删除没有限制条件,在删除表的同时,相关的依赖对象,例如视图,都将被一起删除。
缺省情况是RESTRICT;
- 修改表
表的修改操作包括,添加、删除、修改属性等。修改表的语法如下:
alter table <关系名>
[add <新列名> <数据类型> [完整性约束]]
[drop <完整性约束名>]
[alter column <列名> <数据类型>]
add子句用于增加新列和新的完整性约束条件,drop子句用于删除指定的完整性约束条件,alter column子句用于修改原有的列定义,包括修改列名和数据类型。
【示例1】添加新的属性
alter table instructor2 add firstname varchar(20),
lastname varchar(20);
【示例2】删除已有属性
alter table instructor2 drop
firstname ,lastname ;
【示例3】修改已有属性的数据类型
alter table instructor2 alter column id int;
【示例4】增加某个属性的唯一值的约束条件
alter table instructor2 add unique(id);
(3)数据查询
表单查询
选择查询若干列:
select Sno from Student;
查询全部列:
select * from Student;
查询经过计算的列:
select 2004-Sage from Student;
用户可以通过指定别名来改变查询结果的列标题,这对于含算数表达式、常量、函数名的目标列表达式尤为有用。例如:
select Sname NAME, 'Year of Birth:' BIRTH, 2004-Sage BIRTHDAY,
LOWER(Sdept) DEPARTMENT
from Student;
消除取值重复的行:
select distinct Sno from SC;
查询满足条件的元组
查询满足指定条件的元组可以通过WHERE子句实现。WHERE子句常用的查询条件如下表所示:
查询条件 | 谓词 |
---|---|
比较 | =, >, <, >=, <=, !=, <>, !>, !<, NOT+等比较运算符 |
确定范围 | BETWEEN AND, NOT BETWEEN AND |
确定集合 | IN, NOT IN |
字符匹配 | LIKE, NOT LIKE |
空值 | IS NULL, IS NOT NULL |
多重条件(逻辑运算) | AND,OR,NOT |
(a)比较大小
进行比较的运算符一般包括:
=(等于), >(大于), <(小于), >=(大于等于), <=(小于等于), !=或<>(不等于), !>(不大于), !<(不小于)。
【示例】
select Sname from Student WHERE Sdept = 'CS';
RDBMS执行该查询的一种可能过程是:对Student表进行全表扫描,取出一个元组,检查该元组在Sdept列的值是否等与’CS’。如果相等,则取出Sname列的值形成一个新的元组输出,否则则跳过该元组,取下一个元组。
如果全校有数万个学生,计算机系的学生人数是全校的5%左右,可以在Student表的Sdept列上建立索引,系统会利用该索引找出Sdept='CS’的元组,从中取出Sname列值形成结果关系。这就避免了对Student表的全表扫描,加快查询。注意如果学生较少,索引查找不一定能提高查询效率,系统仍会使用权标扫描。这由查询优化器按照某些规则或估计执行代价来做出选择。
(b)确定范围
谓词BETWEEN…AND…和NOT BETWEEN…AND…可以用来查找属性值在(或不在)指定范围内的元组,其中BETWEEN后是范围的下限(即低值),AND后面是范围的上限(即高值)。
select Sname, Sdept, Sage from Student where Sage between 20 and 30;
(c)确定集合
谓词IN可以用来查找属性值属于指定集合的元组。
【示例】查询计算机系(CS)、数学系(MA)和信息系(IS)学生姓名和学号。
select Sname, Ssex from Student where Sdept IN ('CS', 'MA', 'IS');
与谓词IN相对的谓词是NOT IN,用于查询属性值不属于某个集合的元组。
(d)字符匹配
谓词LIKE可以用来进行字符串匹配。其一般语法格式如下:
[NOT] LIKE '<匹配串>'[ESCAPE '<换码字符>']
其含义是查找指定的属性列值与<匹配串>相匹配的元组。<匹配串>可以是一个完整的字符串,也可以含有通配符%和_。其中:
%(百分号):代表任意长度(长度可以为0)的字符串。例如a%b表示以a开头,以b结尾的任意长度的字符串。如abc、addgb等。
_(下横线):代表任意单个字符。例如:a_b表示以a开头,以b结尾的长度为3的任意字符串。
select * from Student where Sno LIKE '20021232';
等价于
select * from Student where Sno='20021232';
如果LIKE后面匹配串中不含通配符,则可以用=运算符取代LIKE谓词,用!=或者<>运算符取代NOT LIKE谓词。
注意:如果用户要查询的字符串本身就含有通配符%或_,这时就要使用ESCAPE’<换码字符>'短语,对通配符进行转义了。
【示例】
select Cno, Ccredit from Course where Cname LIKE 'DB\_DESGN' ESCAPE '\';
ESCAPE ''表示“\”为换码 字符。这样匹配串中紧跟在“\”后面的字符“”不再具有通配符的含义,转义为普通的“”字符。
select * from Course where Cname LIKE 'DB\_%i__' ESCAPE '\';
这里的匹配串为’DB_%i__’。第一个_ 前面有个换码字符\,所以它被转义为普通的_字符,而后面的两个__前面均没有换码字符\,所以它们仍作为通配字符。
(e)涉及空值的查询
select Sno, Cno from SC where Grade is NULL;
注意:这里的 is 不能用=代替。
(f)多重查询条件
逻辑运算符AND和OR可以用来联结多个查询条件,AND的优先级高于OR,当用户可以用括号改变优先级。
select Sname from Student where Sdept='CS' AND Sage < '20';
select Sname, Ssex from Student where Sdept = 'CS' OR Sdept = 'MA' OR Sdept = 'IS';
(g)ORDER BY子句
用户可以用ORDER BY子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,缺省值为升序。
select Sno, Grade from SC where Cno='3' ORDER BY Grade DESC;
对于空值,若按升序排,含空值的元组将最后显示,若按降序排,空值的元组将最先显示。
(h)聚集函数
为了进一步方便用户使用,增强检索功能,SQL提供了许多的聚集函数,主要有:
COUNT(DISTINCT | ALL] *)//统计元组个数
COUNT([DISTINCT | ALL]<列名>)//统计一列中值的个数
SUM([DISTINCT | ALL]<列名>)//计算一列值的总和(此列必须是数值型)
AVG([DISTINCT | ALL]<列名>)//计算一列的平均值
MAX([DISTINCT | ALL]<列名>)//求一列值中的最大值
MIN([DISTINCT | ALL]<列名>)//求一列值中的最小值
如果指定DISTINCT短语,则表示在计算时要取消指定列中的重复值。如果不指定DISTINCT短语或指定ALL短语(ALL为缺省值),则表示不取消重复值。
(i)GROUP BY子句
GROUP BY子句将查询结果按照某一列或多列的值分组,值相等的为一组。
对查询结果分组的目的是为了细化聚集函数的作用对象。如果未对查询结果进行分组,聚集函数将作用于整个查询结果,分组后,聚集函数将作用于每个组,即每一组都有一个函数值。
select Cno, COUNT(Sno) from SC GROUP BY Cno;
该语句对查询结果按Cno的值分组,所有具有相同Cno值的元组为一组,然后对每一组作用聚集函数COUNT计算,一求得该组的学生人数。
如果分组后还要求按一定的条件对这些组进行筛选,最终只输出满足指定条件的组,则可以使用HAVING短语指定筛选条件。
select Sno from SC GROUP BY Sno HAVING COUNT(3) > 3;
这里先用GROUP BY子句按Sno进行分组,再用聚集函数COUNT对每一组计数。HAVING短语给出了选择组的条件,只有满足条件(即元组个数大于3,表示此学生选修的课超过3门)的组才会被选出来。
where子句与HAVING短语的区别在于作用对象不同。where子句作用于基本表或视图,从中选择满足条件的元组,HAVING短语作用于组,从中选择满足条件的组。
(j)连接查询
若一个查询同时涉及两个以上的表,则称之为连接查询。连接查询是关系数据库中最重要的查询,包括等值连接查询、自然连接查询、非等值连接查询、自身连接查询、外连接查询和复合条件连接查询等。
连接查询的where子句中用来连接两个表的条件称为连接条件或连接谓词,其一般格式为:
[<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2>
当连接运算符为=时,称为等值连接,使用其他运算符称为非等值连接。
(k)嵌套查询
在SQL语句中,一个select-from-where语句称为一个查血块。将一个查询块嵌套在另一个查询块的where子句或者HAVING短语的条件中的查询称为嵌套查询。
(l)集合查询
select语句的查询结果是元组的集合,所以多个select语句的结果可进行集合操作。集合操作主要包括并操作UNION、交操作INTERSECT和差操作EXCEPT。注意,参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同。
select语句是SQL的核心语句,从上面的例子可以看出其语句成分丰富多样,下面总结一下它们的一般格式。
select [all | distinct]<目标表达式>[别名][,<目标表达式> [别名]] ...
from <表名或视图名> [别名][,<表名或视图名> [别名]]...
[where <条件表达式>]
[group by <列名1>[HAVING <条件表达式>]]
[order by <列名2>[ASC | DESC]];
(4)数据控制
SQL的数据控制功能包括事务管理功能和数据保护功能,即数据库的回复、并发控制,数据库的安全性和完整性控制等。SQL语句有:GRANT(授权)、REVOKE(收权)
GRANT语句的一般格式:
GRANT <权限>[,<权限>] ...
[ON <对象名>[,<对象名>]] ...
TO <用户>[,<用户>] ...
[WITH GRANT OPTION];
GRANT语句的功能:将对指定操作对象的指定操作权限授予指定的用户。
操作权限
对象 | 对象类型 | 操作权限 |
---|---|---|
属性列 | TABLE | SELECT, INSERT, UPDATE, DELETE, ALL, RIVIEGES |
视图 | TABLE | SELECT, INSERT, UPDATE, DELETE, ALL, RIVIEGES |
基本表 | TABLE | SELECT, INSERET, UPDATE, DELETE, ALTER, INDEX, ALL, PRIVIEGES |
数据库 | DATABASE | CREATERTAB |
【示例】把修改学生学号和修改学生姓名的权限授权个用户U1
GRANT UPDATE(Sno), UPDATE(Sname)
ON Student
TO U1;
指定了WITH GRANT OPTION子句:表示获得某种权限的用户还可以吧这种权限再授权给别的用户。
没有指定WITH GRANT OPTION子句:获得某种权限的用户只能使用该权限,不能传播该权限。
【示例】
GRANT SELECT
ON Course
TO U1
WITH GRANT OPTION;
REVOKE语句的功能:收回授予某个用户的某种权限。
REVOKE语句的一般格式为:
REVOKE <权限>[,<权限>]
[ON <对象类型> <对象名>]
FROM <用户>[,<用户>]
REVOKE select
ON Student
FROM U1;