SQL语句类型
DML语句:(data manipulation language) 增、删、改、查:insert\update\delete\select
DDL语句:(data definition language) truncate\create\alter\drop
DCL语句:(data control language) commit\rollback
:rollback
必须在commit
之前执行才有效。
数据处理
insert:insert into
单行插入时需加关键字values
,多行插入则不需要。
desc emp;
insert into emp values ( 1001 , 'Tom' , 'ENGINEER' , 7839 , sysdate, 5000 , 200 , 10 ) ;
insert into emp values ( 1002 , 'Bone' , 'CLARK' , 7820 , to_date( '17-12月-82' , 'DD-MON-RR' ) , NULL , 300 , 20 ) ;
insert into emp( empno, ename, sal, deptno) , values ( 1003 , 'Jim' , 6000 , 20 ) ;
insert into emp( empno, ename, sal) values ( 1003 , 'Jim' , null ) ;
使用&
可提高插入数据的效率:
insert into emp( empno, ename, sal) values ( & empno, & ename, & sal) ;
select empno, ename, sal, & t from emp;
select * from & t;
批处理:一次插入多条数据
create table emp10 as select * from emp where 1 = 2 ;
insert into emp10 select * from emp where deptno = 10 ;
insert into emp10( empno, ename, sal, comm)
select empno, ename, sal, comm
from emp
where deptno = 10 ;
update:update ... set
update emp10 set job= 'MANAGER' , hiredate= sysdate, sal= '2000' where empno= 1001 ;
update emp10 set comm = null where empno = 1000 ;
select * from emp where comm = null ;
delete:delete from
delete from emp10 where empno = 1000 ;
delete
和truncate
的区别:
delete
逐条删除表内容,truncate
先摧毁整张表再重建新表。(由于delete
使用频繁,Oracle对delete
优化后执行效率快于truncate
)delete
是DML语句,truncate
是DDL语句。DML语句可闪回(flashback),DDL语句不可闪回。(闪回即做错了一个操作并commit
后,可撤销该操作。)delete
是逐条删除数据,会产生数据碎片(即被删除的那一条数据);而truncate
不会产生碎片。(处理数据碎片的开销:整理碎片、数据连续、行移动。不过Oracle对delete
做了优化,让delete
不会产生碎片。)delete
不会释放空间,truncate
会释放空间。例如,一张大小为10M的表中存有100条数据,用delete
删除这条表后,其中的100条数据没有了,但10M的空间依然还在;而用truncate
摧毁了这张表后,数据和空间都没有了,只留下了重建的空表的表头所占的空间。delete
可回滚(rollback),truncate
不可回滚。
事务
数据库事务由以下部分组成: 一个或多个DML语句、一个DDL语句、一个DCL语句。 事务的特点:一个事务中的若干语句要么都成功、要么都失败。
事务的特性(ACID):
原子性(Atomicity):事务中的全部操作不可分割,要么都完成,要么都不执行; 一致性(Consistency):几个并行执行的事务(如多个终端上)的执行结果必须与按某一串行顺序执行的结果一致,即保证数据库的并发性; 隔离性(Isolation):当多个客户端并发访问数据库时,彼此的事务执行不互相干扰,隔离它们的操作; 了解: Oracle支持三种隔离级别:读已提交read commited(默认)、串行化serializable(即使查询也要等前一个事务结束)、只读read only(当前事务执行时允许其他事务查询); MySQL支持四种隔离级别:读未提交read uncommited、读已提交read commited、可重复读repeatable read(默认)、串行化serializable 持久性(Durability):即使数据库遭遇外界故障(如掉电),系统须保证事务对数据库的修改不丢失。
事务的起始标志:
在Oracle中,事务是自动开启的,以DML语句为开启标志。 执行一个增删改查语句,只要没有提交和回滚,操作都在一个事务中。
事务的结束标志:
显式提交:commit
隐式提交 :
有DDL语句。如,create table
除创建表之外,还会隐式提交create
之前所有没有提交的DML语句。 正常退出:exit
、quit
显式回滚:rollback
隐式回滚:掉电、宕机、非正常退出。
控制事务
savepoint
: DDL、DML、DCL语句都是对数据库事务的控制,除此之外,还引入了保存点savepoint
,可更精细地划分事务。
create table testsp ( tid number, tname varchar2( 20 ) ) ;
set feedback on ;
insert into testsp values ( 1 , 'Tom' ) ;
insert into testsp values ( 2 , 'Mary' ) ;
savepoint aaa;
insert into testsp values ( 3 , 'Moke' ) ;
select * from testsp;
rollback to savepoint aaa;
select * from testsp;
savepoint
用于在事务中间声明一个标记,将一个长事务分隔为多个较小部分,防止出错和丢失数据。若保存点名称重复,会删除前一个保存点。一旦commit
,savepoint
将失效。
创建和管理表
create:create table
create table test1 ( tid number, tname varchar2( 20 ) , hiredate date default sysdate) ;
insert into test1( tid, tname) values ( 11 , 'zhangsan' ) ;
insert into test1 values ( 11 , 'zhangsan' ) ;
数据类型 描述 VARCHAR2(size) 可变长字符数据 CHAR(size) 定长字符数据 NUMBER(p, s) 可变长数值数据 DATE 日期型数据 LONG 可变长字符数据,最大达2G CLOB 字符数据,最大达4G RAW and LONG RAW 原始二进制数据 BLOB 二进制数据,最大达4G BFILE 存储外部文件的二进制数据,最大达4G ROWID 行地址
create table emp10 as select * from emp where 1 = 2 ;
create table emp10 as select * from emp where deptno = 20 ;
create table test2 as
select e. empno, e. ename, e. sal, e. sal* 12 年薪, e. sal* 12 + nvl( comm, 0 ) 年收入, d. dname
from emp e, dept d
where e. deptno = d. deptno;
alter:alter table
alter table test1 add job varchar2( 20 ) ;
alter table test1 modify job varchar2( 40 ) ;
alter table test1 drop column job;
alter table test1 rename column tid to tnumber;
drop:drop table
drop table test1;
select * from test1;
select * from tab;
purge recyclebin;
select * from tab;
drop table test1 purge ;
注意:并不是所有用户都有回收站,管理员用户就没有,它的删除操作不可逆。 当表被删除: 1)数据和表结构都被删除; 2)所有正在运行的相关事务被提交;(因drop语句也是一个DDL语句) 3)所有相关索引被删除; 4)DROP TABLE语句不能回滚,但可闪回。
rename:rename ... to
rename test1 to test2;
约束
约束的种类
Not Null
:非空约束 表示此列数据不能为空Unique
:唯一性约束 不可与已有数据重复。如,电子邮件地址。Primary Key
:主键约束 通过这列的值可唯一确认一行记录,隐含Not Null + Unique
。Foreign Key
:外键约束 制约表与表之间的关系。如,对于部门表dept和员工表emp,不应该在表emp中存在不属于表dept中的任一部门的员工,这里表dept是表emp的外键。也把外键约束称为父子表或主从表,外键表是父表或主表。 问题是,如果要删除父表中的某一列数据,而这列数据又在子表中被引用了,如何处理? 方法一:先将子表的对应内容删除,再删除父表: 定义外键时,通过references
指定参数:ON DELETE CASCADE
(当删除父表时,如发现父表内容被子表引用,级联删除子表引用记录) 方法二:将子表外键一列置为NULL值,断开引用关系,再删除父表: 定义外键时,通过references
指定参数:ON DELETE SET NULL
(先把子表中对应外键置空,再删除父表)Check
:检查性约束 如,密码设置要求不少于6位;某列数据采用下拉列表多选一。
constraint
:给约束起别名(好处是当用户违反某一约束时,提醒信息能做到见名知意)
create table student
( sid number constraint student_PK primary key ,
sname varchar2( 20 ) constraint student_name_notnull not null ,
email varchar2( 20 ) constraint student_email_unique unique
constraint student_email_notnull not null ,
age number constraint student_age_min check ( age > 10 ) ,
gender varchar2( 6 ) constraint gender_female_or_male check ( gender in ( '男' , '女' ) ) ,
deptno number constraint student_FK references dept( deptno) ON DELETE SET NULL
)
insert into student values ( 1 , 'Tom' , 'tom@126.com' , 20 , '男' , 10 ) ;
insert into student values ( 2 , 'Tom' , 'tom@126.com' , 15 , '男' , 10 ) ;
insert into student values ( 3 , 'Tom2' , 'tom2@126.com' , 14 , '男' , 100 ) ;
注意:并不是父表中的所有列都可以设置为子表的外键,而必须是父表中的主键。 查看当前表的约束:
select constraint_name, constraint_Type, search_condition
from user_constraints where table_name= 'STUDENT' ;
其他数据库对象:视图、序列、索引、同义词
视图
视图基于表,是一个逻辑概念,它本身没有数据。 创建视图的语法与创建表一样,除了将关键字table
换为view
。 开启创建视图的权限:
sqlplus / as sysdba;
grant create view to xdb;
简化复杂查询:原来的分组、多表、子查询等可以用一条select * from xxxview
代替。视图可看作是表的复杂的SQL的一种封装。
create view empincomeview
as
select e. empno, e. ename, e. sal, e. sal* 12 annualsal, e. sal* 12 + nvl( comm, 0 ) income, d. dname
from emp e, dept d
where e. deptno = d. deptno;
限制数据访问,隐藏源数据:只看视图的结构和数据是无法知道该视图是怎么来的。
注意:视图不能提高性能;不建议(但不是做不了)通过视图修改表数据(不通过视图做:insert\update\delete
操作),因为视图提供的目的就是为了简化查询。 几点细节:
视图只能创建、删除、替换。(不能修改)
create or replace view empincomeview
as
select . . . from . . . where . . .
with read only;
别名:可写在select子查询各个列的后面,也可写在视图名后 with check option
:
create view testview
as
select * from emp where deptno = 10
with check option ;
删除视图:
drop view testview;
序列(了解)
可理解为数组:[1, 2, … , 20]。初始时,游标指向1前的位置,向后移取出第一个值。每取一次游标后移一次。 序列可提高效率(因序列存于内存中)。常用于指定表中的主键。 创建并使用序列:
create sequence myseq;
create table tableA ( tid number, tname varchar2( 20 ) ) ;
insert into tableA values ( myseq. nextval, 'Tim' ) ;
insert into tableA values ( myseq. nextval, 'Jack' ) ;
select myseq. currval from dual;
select myseq. nextval from dual;
select myseq. currval from dual;
只有将来的序列值会被改变。改变序列的初始值只能通过删除序列之后重建序列实现。 删除序列:
drop sequence myseq;
注意问题: 序列是公有对象,多张表同时使用序列会造成主键不连续;回滚也可能造成主键不连续,因为nextval不会随着rollback操作回退;掉电也可能造成不连续,这是因为序列是存在于内存中的,掉电后内存内容会丢失,且恢复供电后序列直接从21开始。
索引
create index myindex on emp( deptno) ;
drop index myindex;
create index myindex on emp( deptno, job) ;
索引相当于目录,提高数据检索速度。 索引的基本介绍:
独立于表,可存储在与表不同的磁盘或表空间中:它与表相关,但独立存储。它实际上是在逻辑上与表产生联系。 索引被破坏或删除时,不会对表产生影响,只会影响查询速度。 索引一旦建立,用户不需维护,系统为自动维护,而且由系统决定何时使用索引,用户不用在查询语句中指定使用哪个索引。 删除表时,所有基于该表的索引会自动被删除。 通过指针加速Oracle服务器的查询速度。(Oracle实现索引的机制) 通过快速定位数据减少磁盘I\O。
列中数据值分布范围很广; 列经常在where
子句或连接条件中出现; 表经常被访问而且数据量很大(访问的数据量大概占数据总量的2%~4%)。 与上述情况相反的条件下不适合创建索引。另外,若表经常更新,也不适合创建索引,因为维护索引的成本高。
同义词(synonym)
sqlplus hr/ 11
grant select on employees to scott;
select count ( * ) from hr. employees;
create synonym hremp for hr. employees;
conn / as sysdba
grant create synonym to scott;
select count ( * ) from hremp;
同义词、视图等用法在数据保密要求高的机构使用广泛,既不影响对数据的操作,又能保证数据的安全。