Oracle

来源:互联网 发布:济南软件测试招聘 编辑:程序博客网 时间:2024/05/22 17:33



基本介绍:
Oracle 公司也提供应用系统;
我们涉及的是数据库管理系统DBMS(多用户系统);
数据库操作语言SQL——结构化查询语言;
(Structured Query Language)
SQL 操作对象为DB 中的数据,表现形式为——库和表。
Oracle 用表管理表:
一、Oracle
数据库中常用的数据类型
varchar2(长度) 可变长字符串date 日期类型
char(长度) 定长number() 表示整数或者浮点数
clob 字符的大对象blob 二进制的大对象
二、数据库查询
1、SELECT
语句
从表中提取查询数据.语法为:
SELECT [DISTINCT] {*, column1,column2,…}
FROM tablename WHERE {conditions}
GROUP BY {…} HAVING {conditions}
ORDER BY {expressions} [ASC/DESC];
SELECE 语句包括:投影操作(针对字段)、选择操作(针对记录)、连接操作
说明:SELECT 子句用于指定检索数据库的中哪些列,FROM 子句用于指定从哪
一张表或视图中检索数据。
注意:DISTINCT 在9i 中排重并会触发排序;DISTINCT 是字段联合起来不重复。
SQL 语句从性能上对大小写是敏感的,需要有规范来减少对DB 的压力。
Oracle
DB
select
table_name
from
user_tables;
//
查看当前有那些表
desc
s_emp
//
查看表结构(sqlplus
命令) 以上两条很有用
用户表系统表(
数据字典)
telnet
192.168.0.
26
通过sqlplus
命令与数据库建立连接,来操作DDL
、DML
① PATH
中要加入sqlplus
所在的目录
PATH
中追加$ORACLE_HOME/bin
(下面有sqlplus 命令)
用户需要设置两个环境变量:
② ORACLE_HOME
Oracle
安装目录
③ ORACLE_SID
表示连接的数据库//
一定要设置,否则无法连数据库
数据库实例的名字这里的实例名(instance
name)
:tarena
sqlplus
openlab
/
open123
SQL>
表示已经进入SQL
环境。//Oracle
的监听进程:1521
2
2、WHERE
子句。
WHERE 子句用来选择符合条件的记录。(用表达式、函数会影响索引的使用)
between ... and ... 表示结果在这之间,between and 是一个闭区间;
!=,<>,^=
这三个都可以表示不等于;
in (val1,val2,...) 判断结果是否在这个集合中存在; in
等价于:=any
注意val1
、val2

的顺序会影响执行效率,与数据分布有关
like '...' 表示字符串通配查询,'%'表示0 或多个字符, '_' 表示一个字符;
注意字符大小写敏感知道转义的用法:like ‘S/_%’ escape ‘/’
... and ... 表示只有两个条件同时满足;
... or ... 表示条件满足其中之一即可; and 优先级比or 高
all ... 是要求都满足条件;
not ..... 可以与以上的条件产生相反的效果; not
in
等价于: <>all
注意空值的影响,空值与任何值比较结果都为空!
... is null 用来判断值是否为空。
3、ORDER
BY
子句(可以跟:字段名、别名、表达式、位置)
ORDER BY 子句使得SQL 在显示查询结果时将各返回行按顺序排列,返回行的
排列顺序由ORDER BY 子句指定的表达式的值确定。空值当作无穷大判断。
ASC(升序,默认的)
DESC(降序)
order by 目标列名(别名) 排序顺序(不写则默认为升序)
例:select first_name from s_emp order by first_name; //默认为升序
select first_name from s_emp order by dept_id, first_name desc; //升序,降序
三、SQL
常用的命令分类及例子
数据定义语言<操作表的结构>:
DDL
(Data Definition Language)
数据操纵语言<操作表的数据>:
DML
(Data Manipulation Language)
事务控制语言:
TCL
(Transaction Control Language)
create( 创建)
alter(更改)
drop(删除)
insert ( 插入)
delete ( 删除)
update(更新)
select (查找)
commit ( 提交)
savepoint(保存点)
rollback(回滚)
必须要掌握,使用频
度高!
强调:事务处处流淌
在我们的应用中!
3
数据控制语言:grant(授予)和revoke(回收)。与权限有关
DCL
(Data Control Language)
1、数据定义语言DDL
举例:
SQL> create table myTab(no number(4), name varchar2(20)); // 创建一个名为
myTab 的表,包含两列分别为no 和name;
SQL> alter table myTab modify (name varchar2(25)); //修改myTab 中的name 列,
使此列能容纳25 个字符;
SQL> alter table myTab add (tel_no varchar2(20)); //给表myTab 增加一列tel_no;
SQL> alter table myTab drop column tel_no; //删除表myTab 的tel_no 列;
SQL> drop table myTab; //删除表myTab;
SQL> truncate table myTab; //删除表myTab 中的所有行(截断表),注意:此操
作不可以rollback。
2、数据操纵语言DML
举例:
SQL> insert into myTab values('001', 'John'); //向表myTab 中插入一行数据;
SQL> select distinct salary "薪水" from s_emp where salary>1500 order by sal desc;
//选择表中salary 大于1500 的数据,以别名“薪水”显示并按照salary
的降序进行排列输出;
SQL> create table empa as select empno, ename, job, sal from emp;
//从emp 表中选择“empno,ename,job,sal”四列的数据建立新表empa;
SQL> create table empa as select * from emp where 1=2;
//使用一个假条件根据现有表emp 创建一个只包含结构的空表empa;
SQL> delete from empa where sal<1500;
//删除表empa 中sal 小于1500 的行;
SQL> update empa set sal=1500 where sal<1500;
//更新,将表empa 中sal 小于1500 的行的sal 值全部改为1500。
3、事务控制语言TCL
举例:
SQL> commit; //用于提交并结束事务处理;
SQL> savepoint mark1; //保存点类似于标记,用来标记事务中的可回滚点;
SQL> rollback to savepoint mark1; //回滚到保存点mark1。
四、Oracle
数据库函数
注意:dual 表(虚表)是专门用于函数测试和运算的。
单行函数(where 子句只能放单行函数)
4
1、字符函数
字符是大小写敏感的
转小写lower(字段名)
转大写upper(字段名)
首字母大写initcap(字段名)
字符串拼接concat(字段1, 字段2)
截取子串substr(字段名, 起始位置,取字符个数)
字符串长度length(…)
忽略空值nvl(commission_pct, 0) 遇到空值,则用0 代替
例: select first_name, substr(first_name, 2, 2) sub from s_emp;
(从名字的第二个字符开始取两个字符)
select first_name,substr(first_name, -2, 2) sub from s_emp;
(从名字的倒数第二个字符开始取两个字符)
2、数值函数
四舍五入函数round(数据, 保留到小数点后几位)
1 表示保留到小数点后一位; -1 表示保留到小数点前一位。
例:select round(15.26, 1) from dual;
截取数值函数trunc(数据,保留到小数点后几位)
例:select trunc(123.456,1) from dual;
截取到小数点后一位,注意:与round 函数不同,不会四舍五入。
3、日期函数
只要是日期格式,均包括(世纪、年、月、日、时、分、秒)的信息。
日期是格式敏感的! 缺省日期格式:日-月-年DD-MON-RR
修改当前会话的日期格式,会按照指定的格式输出日期:
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
返回当前日期sysdate
例:select sysdate from dual;
另外,date 类型可以运算:
select sysdate-1, sysdate, sysdate+1 from dual; 单位为1 天
select sysdate, sysdate+1/144 from dual; 加10 分钟
两个日期相减表示:相隔多少天。
使用函数:
5
select trunc(add_months(sysdate,1),'MONTH') from dual; //取下个月的首天
months_between(add_months(sysdate,5), sysdate) //两个时间有多少月
add_months(sysdate, -5) //在系统时间5 个月前的时间
last_day(’06-DEC-07’) //一个月的最后一天31-DEC-07
next_day(’06-DEC-07’, ‘FRIDAY’) //求下一个星期五07-DEC-07
补充:(从9i 后才有的)
抽取函数select extract(year from sysdate) from dual; // 2007
select extract(month from sysdate) from dual; // 12
4、不同数据类型间转换函数
将日期转成特定格式字符串tochar(date,'日期格式')
tochar()还可以提取日期信息:to_char(start_date, 'mm')
日期格式要用有效格式,格式大小写敏感'yyyy mm dd hh24:mi:ss'(标准日期
格式)。'year'(年的全拼),'month'(月的全拼),'day'(星期的全拼),'ddspth' (日期的全
拼)
例:select to_char(sysdate,'yyyy mm dd hh24:mi:ss')from dual;
select to_char(sysdate,'year month day ddspth')from dual; //大小写敏感
select to_char(sysdate,'YEAR MONTH DAY DDSPTH')from dual;
将字符串转成日期to_date('...', '日期格式')
主要用于日期的入库。
例:select to_char(to_date('2008 08 08','yyyy mm dd'),'dd-month-yy') from dual;
insert into test1 values(to_date('2007 01 01 10:10:10','yyyy mm dd hh24:mi:ss'));
五、表连接(关联查询)
㈠等值连接
select table1.column1,table2.column2
from table1 t1,table2 t2
where t1.column3=t2.column4;
表连接时,当表与表之间有同名字段时,可以加上表名或表的别名,加以区分,
使用时要用表名.字段名或表别名.字段名(列名)。当表的字段名是唯一时,可以
不用加上表名或表的别名。
注意:当为表起了别名,就不能再使用表名.字段名了。
例如:select e.first_name || ' '|| e.last_name name,
d.name dept_name
from s_emp e, s_dept d
where e.dept_id=d.id;
6
㈡非等值连接
select [表别名1.字段名1],[表别名2.字段名2],...
from 表1 表别名1 ,表2 表别名2
where 表别名1.字段名3 ..... 表别名2.字段名4
....可以使用比较运算符,也可以使用其它的除了'='之外的运算符
例: 查看员工工资级别
select e.ename, e.sal, g.grade
from emp e, salgrade g
where e.sal between g.losal and g.hisal;
㈢自连接
把一个表的两个字段关系转换成两个表字段之间的关系.
select [表别名1.字段名1],[表别名2.字段名2],...
from 表1 表别名1 ,表1 表别名2
where 表别名1.字段名3=表别名2.字段名4;
例:找出员工与他的直属领导
select a.first_name ename, b.first_name cname
from s_emp a, s_emp b
where a.manager_id=b.id;
以上三种连接为内连接,会严格匹配!
㈣外连接
使用一张表中的所有记录去和另一张表中的记录按条件匹配(空值也会匹配),这
个表中的所有记录都会显示。
☆要记录一个都不能少,则在对方的那一边加(+)
等价于
结果为:所有员工及对应部门的记录,包括没有对应部门编号dept_id 的员工记
录。
1. LEFT OUTER JOIN:左外连接
select e.last_name, e.dept_id,
d.name
from s_emp e
left outer join s_dept d
on (e.dept_id = d.id);
select e.last_name, e.dept_id,
d.name
from s_emp e, s_dept d
where e.dept_id=d.id(+);
在加(+)的这一边模拟
数据与之匹配。
第一类问题:掌握哪个部
门没有员工的写法,用外
连接。
select
e.deptno,
d.deptno
from
emp
e,
dept
d
where
e.deptno(+)
=
d.deptno
and
e.deptno
is
null
7
2. RIGHT OUTER JOIN:右外连接
结果为:所有员工及对应部门的记录,包括没有任何员工的部门记录。
3. FULL OUTER JOIN:全外关联
结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id
的员工记录和没有任何员工的部门记录。
六、组函数
group
by
把select 查询的结果集分成几个小组,这个group by 子句可以跟
在select 语句后面或是having 前面。group by 子句也会触发排序操作,会按分
组字段排序。
select [组函数或分组的字段名]... from 表名group by [字段名1],[字段名2],.....;
例:select avg(salary) from s_emp group by dept_id;
注意:① 组函数会忽略空值,但是count(*)除外,他会把空记录也统计在内。
② avg 和sum 这两个函数的参数只能是number 型的。
③ count、max、min 可以使用任意类型做参数。
④ max(..), min(..)求最大值和最小值,
⑤ count(*)统计表中记录数。
例:select min(dept_id), avg(salary) from s_emp where dept_id = 42;
//有组函数,就必须都要求组函数,要过语法关。
select
max(b.name),
avg(a.salary),
max(c.name)
(第二类问题)
from
s_emp
a,
s_dept
b,
s_region
c
where
a.dept_id=b.id
and
b.region_id=c.id
group
by
b.id;
注意:只要写了group by 子句,select 后就只能用group
by
之后的字段或者是组
函数。having 子句可以过滤组函数结果或是分组的信息,并写在group by 子句后。
select e.last_name, d.name
from s_emp e
right outer join s_dept d
on (e.dept_id = d.id);
select e.last_name,d.name
from s_emp e, s_dept d
where e.dept_id(+)=d.id;
select e.dept_id,d.id
from s_emp e
full outer join s_dept d
on (e.dept_id = d.id);
加max()
,
过了语法关
8
七、子查询
可以嵌在sql 语句中的select 语句。
在select 语句中嵌套子查询时,会先执行子查询,返回结果再执行主查询。
一般会将子查询放在运算符的右边。子查询的返回会排重。
注意:在使用子查询时,要注意这个运算符是单行的(也就是只能是单值)
比如=要确认返回的是单行;还是多行运算符(范围,多值.比如in
)。配合使用
子查询返回的结果必须符合运算符的用法。
例: 查询和42 部门员工职位相同的所有员工的姓名.
select first_name||' '||last_name name // 用||
表示字符串拼接
from s_emp
where title in (select title from s_emp
where dept_id=42);
那个部门的平均工资比32
部门的平均工资高?
select
dept_id,
AVG(salary)
from
s_emp
group
by
dept_id
having
avg(salary)>
(select
avg(salary)
from
s_emp
where
dept_id
=
32);
在select 后加子查询: 谁的工资比本部门的平均工资高? (第三类问题)
select
e.first_name,
e.salary,
a.avgsal
from
s_emp,
(select
dept_id,avg(salary)
avgsal
from
s_emp
group
by
dept_id)
a
where
e.dept_id
=
a.dept_id
and
e.salary
>
a.avgsal
范式:
1NF
关系中每一分量不可再分。即不能以集合、序列等作为属性值
2NF
有一个字段唯一且非空的,比如ID

但是数据很可能冗余,会造成数据不一致。
3NF
非主属性间无依赖关系了。在2NF
的基础上拆表。
比如分为student
表class

9
八、约束
针对表中的字段进行定义的。
1
、primary
key
(主键约束PK
)保证实体的完整性,保证记录的唯一。
主键约束,唯一且非空,并且每一个表中只能有一个主键,有两个字段联合作为
主键时,将两个字段组合在一起唯一标识记录,叫做联合主键。
主键约束的定义:
第一种定义形式:
create table test(c number primary key ); 列级约束
第二种定义形式:
create table test(c number , primary key(c) ) ; 表级约束
create table test(c1 number constraints pk_c1 primary key ); 此约束有
名字: pk_c1 <起约束名有利于查错>
create table test(c number , c1 number , primary key (c ,c1) ) ; 用表级约束可
以实现联合主键
2
、foreign
key
(外键约束FK
)保证引用的完整性,外键约束,外键的取值是
受另外一张表中的主键或唯一值的约束,不能够取其他值,只能够引用主键或唯
一键的值,被引用的表,叫做parent table(父表),引用方的表叫做child table
(子表),要想创建子表,就要先创建父表;记录的插入也是如此,先父表后子
表;删除记录,要先删除子表记录,后删除父表记录;要修改记录,如果要修改
父表的记录要保证没有被子表引用。要删表时,要先删子表,后删除父表。(可
以通过使用cascade constraints 选项来删除父表)
carete table parent(c1 number primary key ); 列级约束
create table child (c number primary key , c2 number references
parent(c1));
或表级约束定义:
create table child( c number primary key , c2 number , foreign key(c2)
references parent(c1));
create table child(c1 number primary key, c2 number references parent(c1) on delete
cascade); //级联删除:删父表时,级联删除子表(化为先删子表,后删父表)
create table child(c1 number primary key, c2 number references parent(c1) on delete
set null); //前提:外键可以为空。
3
、not
null
(非空约束NN
)这是一个列级约束,在建表时,在数据类型的后面
加上not null ,也就是在插入时不允许插入空值。
例:create table student(id number primary key,name varchar2(32) not null,address
10
varchar2(32));
4
、unique
(唯一约束UK

唯一约束,允许为空,要求插入的记录中的值是唯一的。
例:create table student(id number,name varchar2(32),address varchar2(32),primary
key (id),unique (address));
check 约束
检查约束,可以按照指定条件,检查记录的插入。check 中不能使用伪列,不能
使用函数,不能引用其他字段。
例:create table sal (a1 number , check(a1>1000));
九、数据字典DD
数据字典是由系统维护的,包含数据库的信息
数据字典视图
user_XXXXX 用户视图
all_XXXXX 所有视图
dba_XXXXX 数据库中所有视图
v$_XXXXX 动态性能视图
dict 或dictionary 表示数据字典的数据字典。
user_constraints 用户的表中管理约束的表。
其中有constraints_name 字段存放的是约束名,constraint_type 字段存放的是约束
的类型,r_constraints_name 字段表示外键引用自何处。
user_cons_column 表,是用户的列级约束表,column_name 字段存放的是约束字
段的名字,position 字段存放的是约束在联合键中的位置。
十、事务Transaction
原子操作,也就是不可分割的操作,必须一起成功一起失败。
保证事务的完整性、一致性要靠日志;
事务的结束动作就是commit 或rollback;
DDL, DCL 语句执行会自动提交commit。
sqlplus 正常退出是会做提交动作的commit;,当系统异常退出时,会执行回滚操
作rollback;。
一个没有结束的事务,叫做活动的事务(active transaction),活动的事务中修改的
数据时,只有本会话(session)才能看见。
11
DML
十一、Oracle
中的伪列
伪列就像Oracle 中的一个表列,但实际上它并未存储在表中。伪列可以从表中
查询,但是不能插入、更新或删除它们的值。常用的伪列:rowid 和rownum。
rowid:数据库中的每一行都有一个行地址,rowid 伪列返回该行地址。可以使用
rowid 值来定位表中的一行。通常情况下,rowid 值可以唯一地标识数据库中的
一行。
rowid 伪列有以下重要用途:
1)能以最快的方式访问表中的一行;
2)能显示表的行是如何存储的。
3)可以作为表中行的唯一标识。
如:SQL> select rowid,ename from emp;
rownum:对于一个查询返回的每一行,rownum 伪列返回一个数值代表的次序。
rownum 伪列特点:
1) 有个特点要么等于1 要么小于某个值, 不能直接等于某个值, 不能大于某
个值。
2)常用于分页显示。
返回的第一行的rownum 值为1,第二行的rownum 值为2,依此类推。通过使
用rownum 伪列,用户可以限制查询返回的行数。
如:SQL>select * from emp where rownum<11; 从emp 表中提取10 条记录。
十二、序列(sequence)

create sequence 序列名;
(不带参数时默认为从1 开始每次递增1,oracle 中为了提高产生序列的效率一
般一次性产生20 个序列放入当前会话的序列池中备用以加快效率)
sequence 的参数:
increment by n 起始值
start with n 递增量
maxvalue n 最大值
minvalue n 最小值
cycle|no cycle 循环
cache n 缓存(第一次取时会一次取多少个id 存起来)
Table 表级共享锁
Row 行级排它锁
12
查看sequence 视图:
desc user_sequences ;
select sequence_name , cache_size , last_number from user_sequences
where sequence_name like 's_';
select 序列名.currval from dual //查看当前的序列数
select 序列名.nextval from dual //查看下一个序列数,它会自动给当前
的序列加1
drop sequence 序列名; //删除序列sequence
十三、视图(View)
视图就相当于一条select 语句,定义了一个视图就是定义了一个sql 语句, 视图不
占空间,使用视图不会提高性能,但是能简化sql 语句。
创建视图:
creating views 视图名;
如:
create or replace views test as select * from test1 where c1=1;
create or replace:如果view 存在就覆盖,不存在才创建。
force|no force:基表存在时使用,不存在时则创建该表。
注意:向视图中插入数据时,会直接插进基表中,查看视图中的数据时,相当于
就是执行创建时的select 语句。
删除视图:
drop views 视图名;
试图的约束:
with read only 视图只读约束
with check option 不允许插入与where 条件不符的记录,类似于check 约束的功
能.
create view test_cc
as select * from test
where c1>10
with check option;
十四、索引(index

建立索引的目的就是为了加快查询速度,建立索引后会使DML 操作效率慢,但是
对用户查询会提高效率。删除一个表时,相对应的索引也会删除。另外,索引是
会进行排序的。
13
创建一个索引:
create index 索引名on 表名(字段名);
create index test_index on test(c1);
删除索引: drop index test_index;
注意:创建索引就是为了减少物理读,索引会减少磁盘block 搜索扫描的时间。
在经常要用到where 的子句的字段,应该使用索引,另外还要看所查询的数据与
全部数据的百分比,表越大,查询的记录越少,索引的效率就越高。
Oracle
查错方法:
ORA-00904
错误信息错误号
比如:
ERROR
at
line
1:
ORA-00904:
"LAST":
invalid
identifier
Oracle
提供的一条命令,Unix
支持,而Windows
不支持。
用!oerr
来寻求帮助:
SQL>
!oerr
ora
904
//
为Unix
系统命令
00904,
00000,
"%s:
invalid
identifier"
//
*Cause:
//
原因
//
*Action:
//
如何解决
SQL>
!oerr
ora
942
00942,
00000,
"table
or
view
does
not
exist"
//
*Cause:
//
*Action:
另外:切换环境,用! 会产生子进程,exit
又退回来。
edit
命令来编辑SQL
语句(
前提:setenv
EDITOR
vi)
!pwd
在/oracledata/oracle/product/9.2.0/bin
下afiedt.buf
缓存原来写的语句
l 1 定位在哪一行,再修改
14
SQL 脚本存成文件
vi crtsql.sql
用sqlplus 去运行脚本
@crtsql.sql 去运行
动态生成SQL
set
head
off
//去头
set
feed
off
//去尾
set
echo
off
//去回显
spool
crtsel.sql
//把命令输出放到一个文件里
select 'select * from '||table_name||';' from user_tables;
spool
off
set
head
on
set
feed
on
exit
//从sqlplus 中退出
运行脚本的两种方式:
sun-server% sqlplus openlab/open123@crtsql.sql
//注意有空格
SQL>@crtsql.sql
//或者这样也可运行脚本
建议大家用SQL 脚本来写程序(一定掌握)