问题列表
1.使用如下语句,建立以下表
create table copy_emp (
empno int(4),
ename varchar(20),
hiredate date,
deptno int(2),
sal double(8,2)
);
2.在上一题所建立的表的基础上,完成下列问题:
(1)在表copy_emp中插入数据,要求sal字段插入空值、部门号50、参加工作时间为2000年1月1日、其他字段随意
(2)在表copy_emp中插入数据,要求把emp表中部门号为10号部门的员工信息插入
(3)修改copy_emp表中数据,要求10号部门所有员工涨20%的工资
(4)修改copy_emp表中sal为空的记录,工资修改为平均工资
(5)把工资为平均工资的员工,工资修改为空
(6)另外打开窗口2查看以上修改
(7)执行commit,窗口2中再次查看以上信息
(8)删除工资为空的员工信息
(9)执行rollback
参考解答
前提补充
- 已经使用了第1题的语句建立了表
- 自己创建的emp表有如下数据
注意点整理
- 由于MySQL不能在同一语句中先select出表中的某些值、再update这个表,这里的一个解决方法是再嵌套了一层select作为一个临时表,这个方法体现在了在4、5两题的答案中。当然,也可能有别的解决方法。
- MySQL默认隔离级别“repeatable read”
同一个事务在读取时,不会受到其他事务读取、写入的影响(查询结果相对重复)
在对数据执行写入操作时,需要等待其他执行了写入操作的事务结束后,才能进行写入。
分解代码
整体流程图如下
Tips:可以点击流程图定位到相关步骤的代码和效果上,点击跳转后文字可以返回流程图
begin;
begin;
insert into copy_emp
values(1, 'Jim', '2020-01-01', 50, null);
select * from copy_emp;
insert into copy_emp
select * from emp where deptno = 10;
select * from copy_emp;
(第3题)【窗口1】事务A——更新10号部门员工工资涨20%
update copy_emp
set sal = 1.2 * sal
where deptno = 10;
select * from copy_emp;
update copy_emp
set sal = (select avg(sal) from (select * from copy_emp) tmp where sal is not null)
where sal is null;
select * from copy_emp;
update copy_emp
set sal = null
where sal = (select avg(sal) from (select * from copy_emp) tmp where sal is not null);
select * from copy_emp;
select * from copy_emp;
commit;
select * from copy_emp;
commit; -- 既然不用了那就提交了吧【事务B完结】
begin;
delete from copy_emp
where sal is null;
select * from copy_emp;
rollback;
select * from copy_emp;
整体代码
以下是Navicat查询窗口1的内容:
-- 0、先开启事务A
begin;
-- 1、事务A——插入一条自定义数据
insert into copy_emp
values(1, 'Jim', '2020-01-01', 50, null);
select * from copy_emp;
-- 2、事务A——插入一条拷贝数据
insert into copy_emp
select * from emp where deptno = 10;
select * from copy_emp;
-- 3、事务A——10号部门员工变为原来的1.2倍
update copy_emp
set sal = 1.2 * sal
where deptno = 10;
select * from copy_emp;
-- 4、事务A——空工资员工工资变为平均工资
update copy_emp
set sal = (select avg(sal) from (select * from copy_emp) tmp where sal is not null)
where sal is null;
select * from copy_emp;
-- 5、事务A——平均工资员工工资变为空工资
update copy_emp
set sal = null
where sal = (select avg(sal) from (select * from copy_emp) tmp where sal is not null);
select * from copy_emp;
-- 7、事务A——提交之前5次操作【事务A完结】
commit;
-- 8、开启事务C、删除空工资员工
begin;
delete from copy_emp
where sal is null;
select * from copy_emp;
-- 9、回滚【事务C完结】
rollback;
select * from copy_emp;
以下是Navicat查询窗口2的内容:
-- 0、先开启事务B(A与B的先后无关紧要)
begin;
-- 6、【在事务A执行了前面5次操作后】事务B——查询copy_emp表的数据
-- 答:没有变化,仍然显示为空表,只有在本次事务提交后才会显示出3条记录
select * from copy_emp;
-- 7、【在事务A执行了前面5次操作并提交后】事务B——查询copy_emp表的数据
-- 答:没有变化,仍然显示为空表,只有在本次事务提交后才会显示出3条记录
select * from copy_emp;
commit; -- 既然不用了那就提交了吧【事务B完结】