-
-dml语句
-
-
3、
delete:删除表中满足
where条件的已有的行
-
-删除
300号部门
delete
from departments
where department_id
=
300;
-
-不带
where条件的
delete会删除表中所有的行。
-
-这叫做清空一张表
delete
from copy_emp;
rollback;
-
-
delete语句中也可以带子查询
-
-删除公关部的所有雇员
delete
from copy_emp
where department_id
=(
select department_id
from departments
where department_name
like
'%Public%');
-
-清空一个表更有效的方法是使用
TRUNCATE语句。
-
-
TRUNCATE语句比
DELETE语句快,原因是:
-
-
TRUNCATE语句是DDL语句,不生成回滚信息。
-
-截断一个表不会触发表的删除触发器
-
-注意:截断表操作不能回滚
-
-如果一个表是一个引用完整性约束的父表,就不能截断该表。
-
-
table COPY_EMP已截断。
truncate
table copy_emp;
-
-数据库事务(
transaction)
-
-数据库事务有一条或者多条dml语句构成,它们形成一个逻辑的
-
-工作单元,这些语句要么全部执行成功,要么全部执行失败。
-
-数据库事务被用来保证数据的完整性和一致性。
-
-在Oracle中,除了dml事务,还有ddl事务和dcl事务。
-
-后面两种事务都由一条语句构成,并且是自动提交的,用户
-
-不能控制。dml事务不是自动提交的,需要用户发出
commit
-
-或者
rollback语句来结束。
-
-Oracle中的事务是自动开始的:当第一条dml语句执行时,
-
-事务自动开始。没有专门开始事务的语句。
-
-Oracle中控制事务的语句有
4条:
-
-
commit:成功提交并结束事务
-
-
rollback:回滚并结束事务,撤销事务所做的所有工作
-
-
savepoint 保存点:在事务中定义一个保存点(实际上就是打一个标签),
-
-以供在后面使用
rollback
to命令来撤销事务所做的部分工作
-
-
rollback
to 保存点:撤销事务所做的部分工作,但是并不结束事务
-
-创建示例表
create
table transaction_demo(
id
number,
name varchar2(
10)
);
-
-提交现在活动的事务
commit;
-
-以下操作自动在一个新的事务中运行
insert
into transaction_demo(id,
name)
values(
10,
'张三');
insert
into transaction_demo(id,
name)
values(
20,
'李四');
-
-定义保存点a
savepoint a;
-
-将李四改为王五
update transaction_demo
set
name
=
'王五'
where id
=
20;
-
-定义保存点b
savepoint b;
delete
from transaction_demo
where id
=
10;
-
-以下决定如何结束前面的事务
-
-撤销事务做的删除操作
rollback
to b;
-
-撤销事务做的
update操作
rollback
to a ;
-
-撤销事务做的所有操作
rollback;
-
-在一个事务中所做的工作,都是在内存中完成的。只有当
-
-事务提交之后,所有修改才写到磁盘文件中。
-
-
1)在一个事务提交之前,其它用户(事务)不能查看到当前事务
-
-对表所做的修改。
insert
into transaction_demo(id,
name)
values(
10,
'张三');
insert
into transaction_demo(id,
name)
values(
20,
'李四');
-
-现在转到sqlplus中开一个新的会话,执行查询:
-
-看不到任何行
select
*
from transaction_demo
-
-提交事务
commit;
-
-
-
-现在再转到sqlplus中执行查询:
-
-可以看到
2行
select
*
from transaction_demo
-
-
2)当前事务对表做了修改操作,如果其它事务也试图来修改同样的
-
-数据,它会被阻塞。
update transaction_demo
set
name
=
'王五'
where id
=
20;
-
-
-
-
-
-现在转到sqlplus中执行同样的查询,会被阻塞:
update transaction_demo
set
name
=
'王五'
where id
=
20;
-
-提交后,sqlplus会话退出阻塞状态
commit;
-
-在
select语句中,可以使用
for
update子句对
-
-表中的行手工的加锁,以阻止其他用户修改这些行。
-
-将所有的销售人员加锁
select last_name,salary
from employees
where job_id
=
'SA_REP'
for
update;
-
-此时,在sqlplus中执行上面同样的语句,会被阻塞。
-
-直到当前事务提交或者回滚
commit;
-
-使用nowait选项,可以在得不到锁时立即退出,不被阻塞
select last_name,salary
from employees
where job_id
=
'SA_REP'
for
update nowait;
-
-
-
-此时,在sqlplus中执行上面同样的语句,不会被阻塞。
-
-使用wait n选项,可以在得不到锁时等待指定的时间。超时后立即退出,不被阻塞
-
-ORA
-
30006: 资源已被占用; 执行操作时出现 WAIT 超时
select last_name,salary
from employees
where job_id
=
'SA_REP'
for
update wait
5;
-
-
FOR
UPDATE
OF
column_name :
-
-这种语法专门针对连接查询的情况,用来指定只对某一张表的行
-
-加锁,而不是把多个表里的行都加锁。
-
-
column_name就是想要加锁的表的列名。可以任选一个。
-
-使用ddl语句创建和管理表
-
-伪列:使用
desc命令查看表结构时看不见的列,但是
-
-在
sql语句中又可以直接使用的列。他是oracle自动提供的
-
-最常用的伪列:
-
-rownum :他是给查询结果集中的行一个唯一的编号。总是从
1
-
-开始编号
-
-rowid:它代表表中任意行的物理存储地址。通过rowid来检索行
-
-是最快捷的方式
-
-rownum用在
where条件中做比较时,只能使用
<、
<
=、
=操作符,
-
-不能使用
>操作符。
select rownum,department_name,manager_id
from departments;
-
-查询部门表的前
5条记录
select department_name,manager_id
from departments
where rownum
<
=
5;
-
-使用等于比较只能写
=
1
select department_name,manager_id
from departments
where rownum
=
1;
-
-空结果集
select department_name,manager_id
from departments
where rownum
>
10;
-
-一个rowid值包含
4个部分:数据文件编号,数据块编号,
-
-行在数据块中的偏移量、数据对象编号
select rowid,department_name,manager_id
from departments ;
-
-使用dbms_rowid包中的函数可以从一个rowid值中得到
-
-各个组成部分的值
select dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid)
from departments
where rownum
=
1;
-
-创建一张表,就是指定构成该表的各个列的信息。
-
-每个列至少要指定列名、数据类型以及宽度。可选的可以指定
-
-默认值、约束等等。
-
-创建一个dept表
create
table dept(
deptno
number(
2),
dname varchar2(
14),
loc varchar2(
13),
created_date
date
default sysdate
);
-
-确认表创建成功
desc dept;
-
-给列定义的默认值,在执行
insert操作时可以用到:
-
-当不给某个列明确赋值时,他将自动得到默认值或者
null值。
insert
into dept(deptno,dname)
values(
10,
'bgs');
-
-定义列的约束
-
-约束的主要作用是为了防止非法数据进入到表中。
-
-在表这个级别强制实现一些业务规则。
-
-约束是对象,他有名字。如果不给约束明确地命名,那么
-
-Oracle服务器就使用格式SYS_Cn生成一个名字,
-
-这里n是一个整数,因此约束名是唯一的。
-
-所有的约束存储在数据字典中
-
-可以在列或者表级别定义约束。
-
-
5大约束:
-
-
1、
not
null:非空约束
-
-
2、
unique:唯一性约束
-
-
3、
primary
key:主键约束
-
-
4、
foreign
key:外键约束
-
-
5、
check:检查约束
-
-记住:约束是对dml操作进行约束的。
-
-
1、
not
null:非空约束
-
-具有非空约束的列,不能存放
null值
create
table test_nn(
id
number
not
null,
name varchar2(
10)
);
-
-对dml操作的影响
insert
into test_nn(id,
name)
values(
10,
'zs');
-
-
SQL 错误: ORA
-
01400: 无法将
NULL 插入 (
"HR".
"TEST_NN".
"ID")
insert
into test_nn(id,
name)
values(
null,
'ls');
-
-
-
-
SQL 错误: ORA
-
01400: 无法将
NULL 插入 (
"HR".
"TEST_NN".
"ID")
insert
into test_nn(
name)
values(
'ls');
-
-
SQL 错误: ORA
-
01407: 无法更新 (
"HR".
"TEST_NN".
"ID") 为
NULL
update test_nn
set id
=
null
where id
=
10;
-
-对
delete操作没有影响
delete
from test_nn;
-
-
2、
unique:唯一性约束
-
-具有唯一性约束的列不能有重复值。即任意两行在该列上的值都是
-
-唯一的
create
table test_uk(
id
number,
name varchar2(
10),
constraint test_uk_id_uk
unique(id)
);
insert
into test_uk(id,
name)
values(
10,
'zs');
-
-
SQL 错误: ORA
-
00001: 违反唯一约束条件 (HR.TEST_UK_ID_UK)
insert
into test_uk(id,
name)
values(
10,
'ww');
insert
into test_uk(id,
name)
values(
20,
'ww');
-
-
SQL 错误: ORA
-
00001: 违反唯一约束条件 (HR.TEST_UK_ID_UK)
update test_uk
set id
=
10
where id
=
20;
-
-
3、
primary
key:主键约束
-
-主键用来唯一地标识标识表中的每一行。在
where条件中根据主键值来
-
-搜索行,可以唯一的定位
1行。
-
-具有主键约束的列
-
-
1)不能有
null值
-
-
2)不能有重复值
-
-因此:
primary
key
=
not
null
+
unique
-
-主键列一般为数字型或者字符串型
create
table test_pk(
id
number
constraint test_pk_id_pk
primary
key,
name varchar2(
20)
);
insert
into test_pk(id,
name)
values(
10,
'zs');
-
-
SQL 错误: ORA
-
00001: 违反唯一约束条件 (HR.TEST_PK_ID_PK)
insert
into test_pk(id,
name)
values(
10,
'ww');
-
-
SQL 错误: ORA
-
01400: 无法将
NULL 插入 (
"HR".
"TEST_PK".
"ID")
insert
into test_pk(id,
name)
values(
null,
'ww');
-
-
SQL 错误: ORA
-
01407: 无法更新 (
"HR".
"TEST_PK".
"ID") 为
NULL
update test_pk
set id
=
null
where id
=
10;
-
-记住:通常不更新主键值。没有任何意义。
-
-
4、
foreign
key:外键约束
-
-又叫做参照完整性约束。具有外键约束的列,意味着
-
-该列的取值不能随便给,它必须参照它所引用的主键或者唯一键
-
-列的取值。
-
-按照外键定义,它所引用的列必须是主键或者唯一键。
-
-默认情况下,外键列的取值可以为
null
-
-外键所引用的主键可以是其它表的,也可以是本表的。
-
-如果引用的是本表的主键,这种情况叫做自引用。
-
-子表和父表
-
-外键所在的表叫做子表,外键引用的表叫父表。
-
-子表和父表是相对而言的,一个表可能既是子表又是父表
-
-修改dept表,添加主键约束
alter
table dept
add
constraint dept_deptno_pk
primary
key(deptno);
create
table test_fk(
id
number,
name varchar2(
10),
deptno
number,
constraint test_fk_deptno_fk
foreign
key(deptno)
references dept(deptno)
);
insert
into test_fk(id,
name,deptno)
values(
10,
'zs',
10);
-
-
SQL 错误: ORA
-
02291: 违反完整约束条件 (HR.TEST_FK_DEPTNO_FK)
- 未找到父项关键字
insert
into test_fk(id,
name,deptno)
values(
20,
'ls',
20);
-
-
-
-
SQL 错误: ORA
-
02291: 违反完整约束条件 (HR.TEST_FK_DEPTNO_FK)
- 未找到父项关键字
update test_fk
set deptno
=
20
where id
=
10;
-
-删除父表中的行
-
-
SQL 错误: ORA
-
02292: 违反完整约束条件 (HR.TEST_FK_DEPTNO_FK)
- 已找到子记录
delete
from dept
where deptno
=
10;
insert
into dept
values(
30,
'办公室',
null,
null);
-
-可以删除。因为子表中没有依赖于该行的子记录
delete
from dept
where deptno
=
30;
-
-外键列可以为
null值
update test_fk
set deptno
=
null
where id
=
10;
-
-默认情况下,删除父表的行时,如果子表中有依赖于该行的
-
-子记录存在,那么oracle会抛出异常,不准删除。
-
-通过在定义外键约束时使用
on
delete
cascade(级联删除)选项,
-
-在删除父表的行时,会将子表中依赖的子记录同时删除,Oracle
-
-不再抛出异常。
drop
table test_fk;
create
table test_fk(
id
number,
name varchar2(
10),
deptno
number,
constraint test_fk_deptno_fk
foreign
key(deptno)
references dept(deptno)
on
delete
cascade
);
insert
into test_fk(id,
name,deptno)
values(
10,
'zs',
10);
-
-删除父表中的行.此时观察子表,记录被删除
delete
from dept
where deptno
=
10;
-
-使用
on
delete
set
null
insert
into dept(deptno,dname)
values(
10,
'办公室');
drop
table test_fk;
create
table test_fk(
id
number,
name varchar2(
10),
deptno
number,
constraint test_fk_deptno_fk
foreign
key(deptno)
references dept(deptno)
on
delete
set
null
);
insert
into test_fk(id,
name,deptno)
values(
10,
'zs',
10);
-
-删除父表中的行.此时观察子表,子记录未被删除,
-
-但是其外键列被设置为
null
delete
from dept
where deptno
=
10;
-
-带子查询的
create
table语句:
-
-这种语法就是使用子查询返回的结果集的结构来创建目标表
-
-的结构。如果子查询还返回行,那么同时将这些行插入到目标表中
-
-目标的列名可以由子查询的
select列表来决定。
-
-如果子查询的
select中包含表达式,要给列别名
-
-注意,这种语法只能将非空约束带入到目标表中,其它的
-
-约束被忽略
create
table dept80
as
select employee_id,last_name,
salary
*
12 annsal,hire_date
from employees
where department_id
=
80;
-
-快速的复制一张表
create
table copy_emp
as
select
*
from employees;
-
-快速的创建一个空表(只要表结构不要数据)
create
table dept801
as
select employee_id,last_name,
salary
*
12 annsal,hire_date
from employees
where
1
=
2;
-
-在
11g中,你可以指定
READ
ONLY 将表置于只读模式。
-
-可以进行一些维护操作
alter
table dept80
read
only;
-
-
SQL 错误: ORA
-
12081: 不允许对表
"HR".
"DEPT80" 进行更新操作
delete
from dept80;
-
-将表切换为读写状态(正常模式)
alter
table dept80
read
write;
-
-删除表
drop
table dept801;
-
-创建使用视图(
view)
-
-视图是一个逻辑表,它本身作为一个
select语句保存在数据字典中
-
-使用视图,可以把表对客户隐藏起来,使得客户不能直接操作
-
-表,从而保护表的数据安全;另外,使用视图可以使客户编写
-
-查询大大简化。
-
-视图主要用作查询。不是所有的视图都可以做dml操作,
-
-有很多限制条件
-
-创建视图,保存部门
80的雇员信息
create
view empvu80
as
select employee_id,last_name,salary
from employees
where department_id
=
80;
-
-查看视图的结构
desc empvu80;
-
-查询视图
select
*
from empvu80;
-
-通过在视图定义的
select语句中使用列别名,就可以控制
-
-视图的列名
create
view salvu50
as
select employee_id id_number,last_name
name,
12
*salary annsal
from employees
where department_id
=
50;
-
-修改视图:带上
or replace关键字
create
or replace
view empvu80(
id_number,
name,sal,department_id
)
as
select employee_id ,first_name||
' '||last_name ,
salary,department_id
from employees
where department_id
=
80;
-
-创建一个复杂视图:使用了函数、
group
by操作
-
-创建视图,保存每个部门的名称、最小薪水、最大薪水和平均薪水
create
or replace
view dept_sum_vu(
name,minsal,maxsal,avgsal
)
as
select d.department_name,
min(e.salary),
max(e.salary),
avg(e.salary)
from employees e
join departments d
on (e.department_id
= d.department_id)
group
by d.department_name;
-
-定义视图时带
with
check
option选项
-
-:这是一个约束,要求对视图进行的dml操作的结果一定要满足
-
-视图的
where条件的限制。如果不满足则抛出异常
create
or replace
view empvu20
as
select
*
from employees
where department_id
=
20
with
check
option
constraint empvu20_ck;
-
-向视图中插入一个部门
20 的雇员
insert
into empvu20(employee_id,last_name,
email,hire_date,job_id,department_id)
values(
207,
'张三',
'abc',sysdate,
'SA_REP',
20);
-
-向视图中插入一个部门
50 的雇员
-
-
SQL 错误: ORA
-
01402: 视图
WITH
CHECK
OPTION
where 子句违规
insert
into empvu20(employee_id,last_name,
email,hire_date,job_id,department_id)
values(
208,
'李四',
'abc',sysdate,
'SA_REP',
50);
-
-使用
with
read
only选项定义只读视图
create
or replace
view empvu10
as
select
*
from employees
where department_id
=
10
with
read
only ;
-
-
SQL 错误: ORA
-
42399: 无法对只读视图执行 DML 操作
delete
from empvu10;
-
-删除视图
drop
view empvu10;
-
-创建使用序列(
sequence)对象
-
-序列对象是一个独立的
schema对象,专门用来生成一系列
-
-自动增长的整数。主要用来给表的主键列赋值。
-
-创建一个序列,用来给部门编号主键字段赋值
create
sequence dept_deptid_seq
increment
by
10
start
with
310
maxvalue
99999
nocycle
nocache;
-
-要访问序列值,使用序列对象.nextval的语法。
-
-序列对象有两个伪列:
-
-nextval:返回序列的下一个可用值
-
-currval:返回序列的当前值。
-
-第一次访问序列,必须使用nextval伪列
insert
into departments(department_id,department_name)
values(dept_deptid_seq.nextval,
'公关部');
select dept_deptid_seq.currval
from dual;
-
-修改序列:不能改起始值。
alter
sequence dept_deptid_seq
increment
by
10
maxvalue
99999
nocycle
nocache;
-
-删除序列:
drop
sequence dept_deptid_seq;
-
-索引的创建和使用
-
-索引用来改进
select语句的执行效率。
-
-索引可以建在一个或者多个列上。建在多个列上的叫做复合索引。
-
-建在一个列上的叫做单列索引。
-
-索引可以自动或者手工创建:
-
-当对列建立了主键或者唯一键约束时,oracle会自动创建唯一索引。
-
-该唯一索引的名字和主键约束的名字完全一样。
-
-除此之外的其它索引都是手工创建的。
-
-索引创建好后,它的使用以及内容的维护都是由oracle自动进行的。
-
-最常用的索引就是b树索引。它对小表和大表都合适。
-
-现在,copy_emp表上没有任何索引,以下查询就会执行
-
-全表扫描。按f10看查询计划
select last_name,salary
from copy_emp
where last_name
=
'King';
-
-在last_name列上建立索引
create
index cemp_lname_idx
on copy_emp(last_name);
-
-此次查询走索引
select last_name,salary
from copy_emp
where last_name
=
'King';
-
-建立多列索引
-
-如果在
where条件中经常以两个或者多个列为条件一起查询,
-
-就可以考虑建多列索引
drop
index cemp_lname_idx;
-
-第一个索引列叫做前导列
create
index cemp_name_idx
on copy_emp(last_name,first_name);
-
-
where里出现前导列,可以使用复合索引
select last_name,salary
from copy_emp
where last_name
=
'King';
select last_name,salary
from copy_emp
where first_name
=
'King';
select last_name,salary
from copy_emp
where last_name
=
'King'
and first_name
=
'King';
-
-删除索引:
drop
index cemp_name_idx;
-
-
5、
check:检查约束
-
-该约束定义一个条件(布尔表达式),列值必须满足该条件
create
table test_ck(
name varchar2(
10),
salary
number
constraint test_ck_sal_ck
check(salary
>
0)
);
insert
into test_ck(
name,salary)
values(
'zs',
1000);
-
-
SQL 错误: ORA
-
02290: 违反检查约束条件 (HR.TEST_CK_SAL_CK)
insert
into test_ck(
name,salary)
values(
'ls',
-
1000);
-
-
-
-
SQL 错误: ORA
-
02290: 违反检查约束条件 (HR.TEST_CK_SAL_CK)
update test_ck
set salary
=
-
500
where
name
=
'zs';