Oracle-SQL开发 —— 数据操作与事务控制

涎涎原创约 3538 字大约 12 分钟...OracleOracle

57-Oracle-SQL开发 —— 数据操作与事务控制.mdopen in new window

注意

本博文仅供学术研究和交流参考,严禁将其用于商业用途。如因违规使用产生的任何法律问题,使用者需自行负责。

概念

  • 数据操作语言

    • Data Manipulation Language ,简称DML,主要用来实现对数据库表中的数据进行操作。
    • 数据操作语言主要包括如下几种:
      • 增加行数据:使用INSERT语句实现
      • 修改行数据:使用UPDATE语句实现
      • 删除行数据:使用DELETE语句实现
      • 合并行数据:按照指定条件合并两个表的数据,使用MERGE语句实现
  • 事务(Transaction)概念

    • 事务:也称工作单元,是由一个或多个SQL语句所组成的操作序列,这些SQL语句作为一个完整的工作单元,要么全部 执行成功,要么全部执行失败。在数据库中,通过事务来 保证数据的一致性。
    • 事务处理语言:Transaction Process Language ,简称TPL, 主要用来对组成事务的DML语句的操作结果进行确认或取消。 确认也就是使DML操作生效,使用提交(COMMIT)命令实现; 取消也就是使DML操作失效,使用回滚(ROLLBACK)命令实现。
    • 通过事务的使用,能防止数据库中出现数据不一致现象。 如两个银行账户进行转账,涉及到两条更新操作,这两条 更新操作只允许全部成功或失败,否则数据会出现不一致的现象。
  • 事务组成

    • 在数据库中,事务由一组相关的DML或SELECT语句,加上一 个TPL语句(COMMIT、ROLLBACK)或一个DDL语句(CREATE、 ALTER、DROP、TRUNCATE等)或一个DCL(GRANT、REVOKE) 语句。
    • 例:如下语句组成两个事务。
      • INSERT….
      • UPDATE….
      • DELETE….
      • SELECT….
      • INSERT…
      • COMMIT;-- 前6条语句,组成第1个事务
      • UPDATE…
      • DELETE….
      • CREATE… ;--后3条语句,组成第2个事务
  • 事务特征可用四个字母的缩写表示:即ACID

    • 原子性(Atomicity)
  • 事务就像“原子”一样,不可被分割,组成事务的DML操作语 句要么全成功,要么全失败,不可能出现部分成功部分失败 的情况。

    • 一致性(Consistency)
    • 一旦事务完成,不管是成功的,还是失败的,整个系统处于 数据一致的状态。
    • 隔离性(Isolation)
  • 一个事务的执行不会被另一个事务所干扰。比如两个人同时 从一个账户从取钱,通过事务的隔离性确保账户余额的正确 性。

    • 持久性(Durability)
    • 也称为永久性,指事务一旦提交,对数据的改变就是永久的, 不可以再被回滚。
  • 显示结束

    • 提交(COMMIT):使用COMMIT命令实现,以成功的方式结束事 务,组成事务的DML语句操作全部生效。
    • 回滚(ROLLBACK):使用ROLLBACK命令实现,以失败的方式结 束事务,组成事务的DML语句操作全部被取消。
  • 隐式结束

    • 隐式提交:当下列任意一种情况发生时,会发生隐式提交
    • 执行一个DDL(CREATE、ALTER、DROP、TRUNCATE、RENAME) 语句;
    • 执行一个DCL(GRANT、REVOKE)语句;
    • 从SQL*Plus正常退出(即使用EXIT或QUIT命令退出);
  • 隐式回滚:当下列任意一种情况发生时,会发生隐式回滚

    • 从SQL*Plus中强行退出
    • 客户端连接到服务器端异常中断
    • 系统崩溃
  • 事务开启

    • 事务自动开启于上一个事务结束后,执行的第一个DML语句。
    • 例如:
    • ….
      • COMMIT; --结束一个事务;
      • SELECT….
      • INSERT…. --开启一个事务
      • UPDATE….
      • DELETE….
      • SELECT….
      • INSERT…
      • COMMIT; --结束一个事务
      • UPDATE… --开启一个事务
      • DELETE….
      • ROLLBACK… ;--结束一个事务
  • 设置保存点

    • 设置保存点:如果在一个事务内,想要回滚到指 定位置,不是回滚到事务的起始点,可以通过保 存点(SAVEPOINT)来实现。
      • SAVEPOINT savepointname;--定义一个保存点语句;
      • ROLLBACK TO savepointname;--回滚到指定保存点
      • 注意:如上两条语句不结束事务的执行
  • 锁的概念

    • 锁用来在多用户并发访问和操作数据库时,保证数据的一致 性的一种机制;
    • 锁由Oracle自动管理,如一个DML操作,ORACLE默认的机制 是在DML操作影响的行记录上自动加锁;
    • 锁在被相关的操作申请并持有后,会一直保持到事务的结 束,事务结束后,锁才会被释放;
    • 查询语句不会锁定任何记录,如果在查询语句后面加FOR UPDATE子句会锁定查询所影响的行记录;
  • 提交或回滚前数据状态

    • 提交(COMMIT)或回滚(ROLLBACK)前的数据状态
      • 数据变化前的状态可以被恢复;
      • 当前会话可以使用SELECT语句来验证DML操作后的结果;
      • 其它会话不能查看由当前用户的DML操作结果;
      • 受影响记录被锁定,也就是其它用户不能改变受影响记录中 的数据;
  • 提交后数据状态

    • 提交(COMMIT) 后的数据状态
      • 在数据库中数据变化成为永久性的,先前的数据状态永久性 的消失;
      • 所有用户/会话都可以查询到提交COMMIT后的结果;
      • 锁定的记录被释放,可以有效地被其他用户操作;
      • 所有的存储节点被清除;
  • 回滚(ROLLBACK)后的数据状态

    • 先前的数据状态被恢复;
    • 锁定的记录被释放;
    • 所有的存储节点被清除;

示例代码

数据查询语言 DQL(Data Query Language): select
数据操作语言 DML(Data Manipulation Language): insert   update   delete
事务处理语言 TPL(Transaction Process Language):commit  rollback

--------------------------------------------------------------------------------------------------
-- 新增数据(插入数据)
--              语法: insert into 表名(列1,列2....) values(值1,值2....);  一次新增一行
--                     insert into 表名(列1,列2....) 子查询;   一次新增N行
--
--              1.列名列表与值列表的个数、类型必须保持一致
--              2.列名列表可以省略,默认值列表给所有列赋值
--              3.值列表中日期、字符串必须使用''单引号括起来
--------------------------------------------------------------------------------------------------
--插入空值NULL   隐含法: 在列名列表中忽略该列。
insert into dept(deptno,dname) values(50,'开发部');

--插入空值NULL  显示法: 指定 NULL关键字或者''
insert into dept(deptno,dname,loc) values(60,'需求部','东软大厦125C');--全部给值
insert into dept(deptno,dname,loc) values(70,'测试部',null);--loc给空值
insert into dept values(80,'实施部','');  --2.列名列表可以省略,默认值列表给所有列赋值
insert into dept values(90,'运维部');     --not OK 没有足够的值

--插入日期值  SYSDATE 函数记录当前日期和时间
insert into emp(empno,ename,hiredate) values(7777,'李四',sysdate);

--插入日期值   可以使用RR日期格式,也可以使用to_date()函数转换YY日期格式
insert into emp(empno,ename,hiredate) values(8888,'李二','2019-08-01');--文字与格式字符串不匹配
insert into emp(empno,ename,hiredate) values(8888,'李二','1-8月-19'); --RR日期格式
insert into emp(empno,ename,hiredate) values(8888,'李二',to_date('2019-08-01','yyyy-mm-dd'));--YY日期格式

--插入特殊字符
insert into dept(deptno,dname) values(50,'~!@#$%^*()-+');--ok
insert into dept(deptno,dname) values(50,'&');           --ok   
insert into dept(deptno,dname) values(50,'&需求部');-- not OK    &修饰的字符表示一个变量,等待用户输入变量值

insert into dept(deptno,dname) values(50,'\&需求部');--not ok
insert into dept(deptno,dname) values(50,'&' || '需求部'); --ok
insert into dept(deptno,dname) values(50,chr(38) || '需求部'); --ok

--ascii() 查看指定字符的ascii编码
select ascii('&') from dual; --38

--chr() 查看指定ascii编码代表的字符
select chr(38) from dual;

----------------------
--批量新增(备份数据)
----------------------
1. 将部门10所有的员工信息备份到emp_dept10表中
①复制表结构:创建表emp_dept10,且结构与emp表一致
create table emp_dept10 as select * from emp;           --1.复制emp表的表结构与所有数据    
create table emp_dept10 as select * from emp where 1=0; --1.仅复制emp表的表结构

② 使用子查询批量新增数据:将部门10的员工数据备份到emp_dept10表中
insert into emp_dept10 select * from emp where deptno = 10;--2.复制所有列数据   
insert into emp_dept10(empno,ename,hiredate) select empno,ename,hiredate from emp where deptno = 10;--2.复制指定列数据

--------------------------------------------------------------------------------------------------
-- 修改数据
--              语法: update 表名 set 列名1=值1[,列名2=值2.....]  [where 限制条件]
--------------------------------------------------------------------------------------------------
--使用 WHERE 子句指定要修改的记录
1.把员工编号为7782的部门编号修改为20
update emp set deptno = 20 where empno = 7782;

--如果要修改所有记录,WHERE子句可以忽略
2.把所有员工的部门编号修改为20
update emp set deptno = 20;

--一次修改多列
3.把部门编号为10的员工,部门编号调整为20,工资增加100
update emp set deptno = 20,sal = sal+100 where deptno = 10;

--嵌入子查询修改
4.把部门编号为10的员工,部门编号调整为20,工资在原有的基础上,增加所有人的平均工资
select avg(sal) from emp;--1.所有人的平均工资  2073.5
update emp set deptno=20,sal= sal+(select avg(sal) from emp) where deptno = 10;

--修改记录时的完整性约束错误
5.把部门编号为10的员工,部门编号调整为55
update emp set deptno=55 where deptno =10;--not ok 未找到父项关键字  emp.deptno 的数据来源于 dept.deptno,此时dept中没有55编号的部门存在

--相关子查询修改
1.在emp中新增dname列
alter table emp add(dname varchar2(14));

2.将emp表中的dname更新为实际部门的名称
update emp set dname = (select dname from dept where deptno = emp.deptno);

--练习
2.修改奖金为null的员工,奖金设置为0
update emp set comm = 0 where comm is null;

select * from emp where comm = null;--null与任意值计算均为null
select * from emp where comm in(null);--null与任意值计算均为null

--------------------------------------------------------------------------------------------------
-- 删除数据
--              语法: delete [from] 表名  [where 限制条件]
--------------------------------------------------------------------------------------------------
--删除选中记录
1.删除职位是CLERK的员工记录
delete from emp where job = 'CLERK';

--删除全部记录
2.删除所有员工记录
delete from emp;
delete emp;

--基于另一个表删除本表记录
3.删除部门SALES的员工
select deptno from dept where dname = 'SALES';--1.SALES的部门编号为多少?  30
delete from emp where deptno = (select deptno from dept where dname = 'SALES');

--删除记录时的完整性约束错误
4.删除部门编号为10的部门记录
delete from dept where deptno = 10; --not ok 已找到子记录  因为emp.deptno引用dept.deptno,而dept.deptno为10的部门已经存在3个员工

--相关DELETE
5.删除曾经做过入职的员工记录
delete from emp where 曾经做过入职;
delete from emp where exists (select * from emp_jobhistory where empno = emp.empno);

6.删除没有员工的部门记录
delete from dept where 没有员工的部门;
delete from dept where not exists (select * from emp where deptno = dept.deptno);

--------------------------------------------------------------------------------------------------
-- 事务管理: 由一组SQL语句组成的管理单元,要么全部执行成功,要么全部执行失败
--              
--       事务四大特性:
--             1. 原子性:一个事务中所有的SQL语句,执行时,要么全部执行成功,要么全部执行失败
--             2. 一致性:不论SQL语句执行成功,还是失败,整个数据处于平衡状态。
--             3. 隔离性:事务与事务之间相互隔离,互不影响
--             4. 持久性:一旦数据被提交,永久性被保存到数据库中,不能再撤回
--
--       事务开启:上一个事务结束以后,执行下一个DML(增、删、改)语句即开始新的事务
--
--       事务结束:
--                1.显示结束
--                       commit:显示提交
--                       rollback:显示回滚(撤销所有的操作)
--
--                2.隐式结束
--                      隐式提交:当下列任意一种情况发生时,会发生隐式提交
--                              1.执行一个DDL(CREATE、ALTER、DROP、TRUNCATE、RENAME)语句;
--                              2.执行一个DCL(GRANT、REVOKE)语句;
--                              3.从SQL*Plus正常退出(即使用EXIT或QUIT命令退出);
--
--                      隐式回滚:当下列任意一种情况发生时,会发生隐式回滚
--                              1. 从SQL*Plus中强行退出
--                              2. 客户端连接到服务器端异常中断
--                              3. 系统崩溃

--------------------------------------------------------------------------------------------------
--开启事务
insert into dept(deptno,dname) values(50,'财务部');
insert into dept(deptno,dname) values(60,'人力资源部');
rollback;--显示回滚,事务结束

insert into dept(deptno,dname) values(70,'后勤部');
commit;--显示提交,事务结束

------------------------------------------------------
--设置保存点
insert into dept(deptno,dname) values(81,'需求部');
savepoint poin1;--设置保存点1
insert into dept(deptno,dname) values(82,'UI部');
insert into dept(deptno,dname) values(83,'前端部');
savepoint poin2;--设置保存点2
insert into dept(deptno,dname) values(84,'开发部');
insert into dept(deptno,dname) values(85,'测试部');
savepoint poin3;--设置保存点3
insert into dept(deptno,dname) values(86,'实施部');

rollback to poin2;--回滚保存点2的位置
commit; --提交部分事务SQL语句

rollback;--事务已经被提交,不可能再被回滚
------------------------------------------------------

------------------------------------------------------
-- 锁:
--      
--      行级锁  和  表级锁             (悲观锁 和  乐观锁)
--
--      行级锁: ORACLE默认的机制是在DML操作影响的行记录上自动加锁
--              当会话1在修改指定行数据,且没有commit提交事务或者rollback回滚事务之前,
--              该数据行被锁定,其他会话2不允许修改该数据。
--              如果会话1结束事务,锁释放,其他会话2可以继续操作该数据
--
--      表级锁:当会话1在操作指定数据时,表将被锁定,其他会话不允许对表结构进行修改(新增列、修改列、删除列)
------------------------------------------------------
--会话1 (执行一个事务)
update dept set loc='125C教室' where deptno = 83;
select * from dept;

--会话2(执行一个事务)
delete from dept where deptno = 50;
select * from dept;

分割线


相关信息

以上就是我关于 Oracle-SQL开发 —— 数据操作与事务控制 知识点的整理与总结的全部内容,希望对你有帮助。。。。。。。

上次编辑于:
贡献者: 涎涎
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.4