前言
本文针对考纲上的30分sql应用题所涉及到的知识进行归纳总结。
会分为两篇文章,此篇为mysql语句。
mysql基础语句
ddl
Data Definition Language,数据定义语言。create,drop,alter等定义表结构的语句。
示例1 创建表
- 主键外键定义
- 非空约束
- 唯一约束
CREATE TABLE emp (
id INT NOT NULL UNIQUE,
name VARCHAR(20),
password VARCHAR(20),
address VARCHAR(30),
salary DOUBLE,
dep_id INT,
primary key (id),
constraint fk_emp_dept foreign key(dep_id)references dept(id)
);
- 增添检查约束
alter table emp add constraint CK_emp_salary check(salary>0 and salary<200000);
dcl
Data Control Language,数据控制语句。grant,revoke之类的。
授权
示例:授予用户学生成绩数据库中对所有表的select,delete权限。并且允许其把权限授予他人。
直接授权:
grant select,delete on xscj.* to user1 with grant option;
用角色授权:
create role role1;
grant select,delete on xscj.* to role1 with grant option;
grant role1 to user1;
收回权限
revoke select,delete on xscj.* from user1;
dml
Data Manipulation Language,数据操作语句。必考。按pta题集复习。
结合事务
- 事务
将员工'E001'转部门,从'行政部'门转至'人事部',并成为人事部门的经理(注意事务成功与失败的两种情况处理
-- 开启自动提交事务
START TRANSACTION;
-- 将员工'E001'转至人事部
UPDATE emp
SET dno = (SELECT dno FROM dept WHERE dname = '人事部')
WHERE eno = 'E001';
-- 检查第一个UPDATE语句的影响行数
IF ROW_COUNT() = 0 THEN
-- 第一个UPDATE语句失败,回滚事务
ROLLBACK;
ELSE
-- 将员工'E001'设为人事部门经理
UPDATE dept
SET mgr_eno = 'E001'
WHERE dname = '人事部';
-- 检查第二个UPDATE语句的影响行数
IF ROW_COUNT() = 0 THEN
-- 第二个UPDATE语句失败,回滚事务
ROLLBACK;
ELSE
-- 两个UPDATE语句都成功,提交事务
COMMIT;
END IF;
END IF;
索引
不应该在这里考察,应该是和关系代数语法树一起考。
分类
索引分为普通索引、唯一性索引、全文索引、单列索引、多列索引。
实现方法有B+树(分聚集索引和非聚集),哈希。
聚集索引是逻辑和物理上都顺序存放的,树叶子结点是数据。
非聚集索引只是逻辑上顺序存放,叶子结点是主键和物理地址。
格式
CREATE <索引名> ON <表名> (<列名> [<长度>] [ ASC | DESC])
示例:create index idx_name on t_dept(name);
推荐阅读:
mysql索引分类
mysql索引介绍
创建索引三种方式
视图
示例:为表 sc 创建一个视图 s_grade(sno,sname,cou_cnt,avg_grade,fail_cnt),包括有各个学生学号、姓名、选修课程的门数、平均分及不及格门数。
create view s_grade as
select stu.sno,
sname,
count(cno) as cou_cnt,
ifnull(AVG(sc.grade), 0) as avg_grade,
sum( if( grade<60 ,1,0) ) as fail_cnt
from sc left join stu on stu.sno=sc.sno
group by stu.sno;
行列子集视图
从单个基本表导出的,并且只是去掉了基本表的某些行和某些列,但保留了主码,则称这类视图为行列子集视图。
可更新性
行列子集视图可以更新。
想更新视图,那么必须确保视图的定义满足以下条件:
视图必须只引用一个基本表。
视图的SELECT语句必须是可删除的,即它不能包含聚合函数、计算列、GROUP BY子句等。
视图必须包含唯一标识行的列,通常是主键。
不可更新的视图情形如下:
- 包含聚合函数,如 SUM(), MIN(), MAX(), COUNT()等。
- 包含 DISTINCT、GROUP BY、HAVING 和 UNION、UNION ALL 等关键字。
- 包含子查询。
- 引用不可更新视图。
- 创建视图时使用临时表,即设置 ALGORITHM = TEMPTABLE。
- 仅引用常量值,即常量视图。
存储过程
- 会结合事务一起考
示例1 带返回值
创建存储过程 P4,输入某课程名,查询该课程的平均分,选课人数并输出之。
create procedure p4(acname char(32),out avg_grd decimal(4,1),out cnt_stu int)
begin
select IFNULL(avg(grade),0),IFNULL(count(sno),0)
into avg_grd,cnt_stu
from cou left join sc on cou.cno = sc.cno
where cou.cname = acname;
end;
call p4('C语言',@avg,@cnt);
select @avg,@cnt;
示例2 游标
创建存储过程 P8,查询每个学生在每个学期所学课程门数、平均分以及不及格的课程门数。
要求:使用游标,取出 stu 表中每个学生学号,逐个学生调用存储过程 P7,将每个学生的每个学期的课程门数、平均分以及不及格的课程门数插入到临时表中。最终查询该临时表显示结果集。
注意:临时表在当前用户会话期间都存在,第一次调用 P7 之前,应先删除该临时表,运行存储过程 P8 后,将创建的临时表删除。
create procedure p8()
begin
declare asno varchar(8);
declare done int default 0;
declare cur_stu cursor for
select sno from stu;
declare continue handler for not found set done = 1;
open cur_stu;
fetch cur_stu into asno;
repeat
call p7(asno);
fetch cur_stu into asno;
until done = 1
end repeat;
close cur_stu;
end;
示例3 结合简单事务
创建存储过程 P1 删除某部门及其相关信息:
DELIMITER //
CREATE PROCEDURE P1(IN department_id VARCHAR(10))
BEGIN
-- 定义异常处理方式
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error occurred during the transaction';
END;
START TRANSACTION;
-- 删除部门职工
DELETE FROM employees WHERE department_id = department_id;
-- 删除部门
DELETE FROM departments WHERE department_id = department_id;
COMMIT;
END //
DELIMITER ;
触发器
当 major 表删除一条专业记录时,检查该专业在 stu 表中是否已经存在学生记录,如果已经存在,将原该专业学生的 mno 全部置为空。如果修改某专业的 mno,也随之修改在 stu 表中该专业学生的 mno 值。
delimiter //
create trigger tri_bfdlt_mj before delete on major for each row
begin
if (select count(*) from stu where stu.mno=old.mno) > 0 then
update stu
set stu.mno = null
where stu.mno = old.mno;
end if;
end//
delimiter ;