ORACLE:DML

目录

一、数据类型DML、DDL、DCL、DQL、TCL

二、DML

INSERT

UPDATE

DELETE

补充:MERGE

三、TCL

事务ACID属性

COMMIT

ROLLBACK

SAVEPOINT

排它锁

共享锁

select for update

死锁


一、数据类型DML、DDL、DCL、DQL、TCL

DML: 数据操纵语言 Data Manipulation Language
  • insert:增
  • update:改
  • delete:删
  • merge:能够在一个 SQL 语句中对一个表同时执行 inserts updates 操作

DDL:数据定义语言 Data Definition Language

  • create:创建表、视图、索引、同义词和其他对象
  •  alter:修改表对象结构、属性、名称
  • drop:删除数据库对象
  • truncate:截断表
DCL: 数据控制语言 Data Control Language
  • grant:授予用户权限
  • revoke:收回用户权限

 DQL:数据查询语言 Data Query Language

  • select
TCL: 事务控制语言 Transaction Control Languag
  •  commit:提交事务
  • rollback:回滚(撤销事务)
  • savepoint:在会话中设置一个保存点,将来通过 rollback 语句可以回滚到该位置

二、DML

INSERT

inset into 表名(column,column,....) values(value1,value2,.....)

插入一行

*数值类型数据可以不用引号

*列名和值一一对应

insert into dept(deptno,dname,loc) values(50,'DEVELOPMENT','CQ');

如果不声明那些列要插入数据,则values中必须体现所有列:

insert into dept values(50,'DEVELOPMENT','CQ');

空值的插入:

1、 省略插入

insert into dept(deptno,dname) values(50,'DEVELOPMENT');

2、指定NULL

insert into dept(deptno,dname,loc) values(50,'DEVELOPMENT',NULL);

 常见错误:

  • 对not null列使用null
  • 违反唯一约束
  • 数据类型不匹配
  • 值不在列约束范围内

 从一张表中拷贝行:

  • 不能使用values
  • 子查询中的列要与insert子句中的列相匹配
例
create table dept1 as select * from dept where 1=2;

Table created.

select * from dept1;

no rows selected

insert into dept1 select * from dept where deptno=10;

1 row created.

select * from dept1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK

 插入日期:

  • 可以使用to_date
例
insert into emp values (2296,'AROMANO','SALESMAN',7782, TO_DATE('2022-11-22','yyyy-mm-dd'),1300,null,10);

1 row created.

select * from emp where empno=2296;

     EMPNO ENAME      JOB	       MGR HIREDATE	    SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      2296 AROMANO    SALESMAN	      7782 22-NOV-22	   1300 		   10

同时向多张表插入多条数据:

insert all

    into 表1 values()

    into 表2 values()

    into 表3 values()

            .......

select ... from 表 where ...

例:向10部门和20号部门分别插入相关员工
insert all 
when deptno = 10 then into emp10 values (empno,ename,deptno) 
when deptno = 20 then into emp20 values (empno,ename,deptno) 
select empno,ename,deptno from emp;

8 rows created.

SCOTT@prod>select * from emp10;

     EMPNO ENAME	  DEPTNO
---------- ---------- ----------
      7782 CLARK	      10
      7839 KING 	      10
      7934 MILLER	      10

UPDATE

update from 表名 set column1='value1',column2='value2',......columnn='valuen' where condition

update dept set loc='aab' where deptno=40; 

多列子查询可以这样:

update emp set (job,deptno) = (select job,deptno from emp where empno=7499) where empno = 7698;

基于另一张表进行修改: 

例:
update emp set deptno=(select deptno from emp where empno=7369) where empno=7196;

改为空值:

1、set 属性=NULL

2、set 属性=''

where 后不能使用=NULL 、='' 、<>'' 、<>null,可以使用 is NULL 或者is NOT NULL

 关联子查询更新:

例:
创建测试表:
create table emp1 as select empno,ename,deptno from emp;
alter table emp1 add(loc varchar2(10));
select * from emp1;

     EMPNO ENAME	  DEPTNO LOC
---------- ---------- ---------- ----------
      7369 SMITH	      20
      7499 ALLEN	      30
      7521 WARD 	      30
update emp1 e set loc=(select loc from dept d where e.deptno=d.deptno);
select * from emp1;

     EMPNO ENAME	  DEPTNO LOC
---------- ---------- ---------- ----------
      7369 SMITH	      20 DALLAS
      7499 ALLEN	      30 CHICAGO
      7521 WARD 	      30 CHICAGO

DELETE

delete from 表名 where 条件

注:不加where则删除表中所有数据

补充:MERGE

使用原始表更新目标表数据

如果存在就更新(update),不存在就插入(insert) 

例:
create table test1 as select * from dept where 1=2; 
create table test2 as select * from dept; 
insert into test1 values (10,'DBA','BEIJING'); 
insert into test1 values(20,'ORACLE','SHANGHAI');
commit;
select * from test1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 DBA		  BEIJING
	20 ORACLE	  SHANGHAI

select * from test2;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK
	20 RESEARCH	  DALLAS
	30 SALES	  CHICAGO
	40 OPERATIONS	  BOSTON
merge into test1 t1 using test2 t2 on (t1.deptno = t2.deptno) 
2 when matched then 
3 update set t1.dname=t2.dname,t1.loc=t2.loc 
4 when not matched then 
5 insert (deptno,dname,loc) values (t2.deptno,t2.dname,t2.loc);
select * from test1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK
	20 RESEARCH	  DALLAS
	40 OPERATIONS	  BOSTON
	30 SALES	  CHICAGO

 上述如果使用子查询,需要分别执行update和insert

update test1 set (dname,loc)=(select dname,loc from test2 where test1.deptno=test2.deptno);

insert into test1 select * from test2 where deptno not in(select deptno from test1);

三、TCL

数据库事务:

第一个DML语句作为开始

以如下行为作为结束:

  • COMMIT或者ROLLBACK语句
  • DDL或者DCL语句(自动提交)
  • SQL developer或SQL Plus用户退出
  • 系统崩溃

sqlplus异常中止时自动进行隐式回滚

事务ACID属性

任何关系型数据库都必须通过ACID测试

  • 原子性 A tomicity 一个事务的所有部分必须都完成,或者都不完成。
    一致性  Consistency 查询的结果必须与数据库在查询开始时的状态一致。
    隔离性  Isolation 除了作出变更的会话,其他会话都无法看到未提交的数据。
    持久性  Durability 事务一旦完成,所有用户必须能够立刻看到所做的变更,同时数据库必须保证这些变 更不会丢失。(数据库通过日志保持事务的持久性)

COMMIT

commit 保存从会话中 最后一次提交 之后对数据库所做的修改。
commit 对数据库作出 永久 的变动,一旦提交之后,这些变动就 无法通过 rollback 语句撤销。
显示提交:commit语句
隐式提交:DDL或DCL语句、SQLPlus正常退出

执行commit或rollback前的数据库状态

  •  改变前的数据状态是可恢复的
  • 执行DML语句的用户可以用select查询之前的修改
  • 其他用户不能看到当前用户做的改变,直到用户结束事务
  • DML涉及到的行被锁定,其他用户不能修改
例:
update dept1 set loc='CQ' where deptno=10; 

1 row updated.

select * from dept1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  CQ
新开session:
select * from dept1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK
数据并没有改变
update dept1 set loc='SC' where deptno=10;
此时数据开启事务锁,处于一直等待中,当第一个session事务结束后,第二个事务DML开始运行

commit提交之后的数据状态:

  • 数据的改变保存在数据库中
  • 以前的数据被覆盖
  • 所以用户可以查看结果
  • 受影响行锁定被解除,其他用户可进行操作
  • 所有保存点(savepoint)被删除

ROLLBACK

rollback 撤销了执行该命令的用户在指定的会话中对数据库所做的修改。
rollback 不会撤销已经提交过的修改。
显示回滚:rollback语句
隐式回滚:异常退出(如直接关闭session)、系统崩溃
提交rollback后的数据库状态
  • 数据更改被撤销
  • 数据恢复到以前状态
  • 数据锁被释放

SAVEPOINT

  • savepoint 在一个 事务内 建立保存点,使后续的 rollback 语句可以保存点位置进行撤销操作。 实现未提交事务的部分回滚
  • savepoint需要一个名称且不能重复,如果名称重复,新的savepoint会覆盖旧的;
  • 一旦事务提交(显示或隐式)所以savepoint都将从被清除(内存中);
  • 若回到前面的savepoint,则后面的savepoint会被清除。
例
create table dept1 as select * from dept;
select * from dept1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK
	20 RESEARCH	  DALLAS
	30 SALES	  CHICAGO
	40 OPERATIONS	  BOSTON
insert into dept1 values (50,'a',null);

savepoint stp1;

select * from dept1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK
	20 RESEARCH	  DALLAS
	30 SALES	  CHICAGO
	40 OPERATIONS	  BOSTON
	50 a
insert into dept1 values (60,'b',null);

savepoint stp2;

select * from dept1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK
	20 RESEARCH	  DALLAS
	30 SALES	  CHICAGO
	40 OPERATIONS	  BOSTON
	50 a
	60 b
rollback to stp1;

select * from dept1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK
	20 RESEARCH	  DALLAS
	30 SALES	  CHICAGO
	40 OPERATIONS	  BOSTON
	50 a
rollback;

select * from dept1;

    DEPTNO DNAME	  LOC
---------- -------------- -------------
	10 ACCOUNTING	  NEW YORK
	20 RESEARCH	  DALLAS
	30 SALES	  CHICAGO
	40 OPERATIONS	  BOSTON

DML操作时用到两种锁:

  • 受影响记录(行)上的 排它锁 exclusive
  • 受影响表上的 共享锁 shared

排它锁

只有一份,我加锁后,其他人不能加锁,只能等待;
行级别,保护这行的数据,防止其 他会话修改这些行;
只锁定修改的行。
如:session1修改一行数据,session2修改此行会等待,但可以修改其他行。

共享锁

可以加多份;

表级别,保护表的结构,防止其他会话使用 DDL 语句修改表的定义。 

如:session1 做修改时,session2 不能把表、字段删了。

select for update

例:
session1
select * from emp where empno=7788 for update;
session2
delete from emp where empno=7788;----会一直等待
select * from emp where empno = 7788 for update;-----无法添加
session1 ROLLBACK或commit后session2可操作

死锁

例:当session1在等待session2结束,session2在等待session1结束就会造成死锁

例:
session1:
update emp set sal=9999 where empno=7788;
session2:
update emp set sal=8888 where empno=7566;
update emp set sal=7777 where empno=7788;
session1:
update emp set sal=5555 where empno=7566;
此时,session1第一条语句执行后事务开始未结束,
session2第二条语句执行时会等待session1结束,
此时session1再执行第二条语句时会等待session2的事务结束,
双方一直等待,死锁形成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值