从零开始学习Oracle—安装及删除
-.要求:
ORACLE9i 9.0.1 空间1.76G
ORACLE9i 9.0.2 空间2.86G
事务处理 -- 增 删除 修改频繁
数据仓库 -- 查询 频繁
GBK --多200个字左右(偏僻字)
GB2312
SETUP.exe 双击
启动ORACLE数据库 OracleServiceOrac 服务 多启动几次
OracleOraHome90TNSListener 服务
如果启动不了Listener(监听器)
<1>改注册表
ImagePath D:\oracle\ora90\BIN\TNSLSNR
<2>用命令行启动
cmd -> tnslsnr 最小化
tNSlsnter 监听器 如果无法启动
运行cmd 切换到DOS界面 敲tnslsnr 窗口不要关闭
<3>D:\oracle\ora90\network\ADMIN
listener.ora 文本文件
HOST=localhost或机器名
存盘
2,操作Oracle数据库的工具
ORACLE SQL*PLUS 字符界面 ORACLE自带
sqlplusw.exe windows窗口下的sqlplus
sqlplus.exe DOS下的sqlplus
用户名scott 密码tiger 普通用户
system manager 超级用户
sys change_on_install 超级用户 比system权限还要大
SQLPLUS下的常用命令
show user 察看用户
connect 用户名/密码 连接到指定用户
connect scott/tiger
select * from tab where tabtype='TABLE'; 察看当前用户下的表
select count(*) from dept; 查询表dept中记录的行数
desc dept 察看表dept的结构
quit/exit 退出
clear screen 清除屏幕
set linesize 200 设置一行显示200个字符
set pagesize 20 设置每页显示20行
spool 文件名 (spool c:\abc.txt) 作日志文件命令
spool off
修改D:\oracle\ora90\sqlplus\admin\glogin.sql文件
可以设置SQLPLUS的环境
set linesize 200
set pagesize 20
ORACLE 企业管理器 (OEM) 图形界面
PL/SQL Developer 第三方软件 ORACLE不带的
SQLPLUS /nolog nolog是不登陆
浏览器使用oracle (isqlplus)
D:\oracle\ora90\Apache\Apache\conf\httpd.conf
修改80端口 -> 8001
http://localhost:8001/isqlplus
用工具 ORACLE SQL*PLUS验证数据库是否启动
用户名system 密码manager
出现 连接到 和 SQL>符号 说明数据库已经可用了
默认用户:
超级用户: 用户名system/密码manager
用户名sys/密码change_on_install
普通的用户: 用户名scott/密码tiger
注意的问题:安装的源程序放在什么目录下??
<1>目录中不要出现中文名字的目录
<2>数据库的名字不要是中文,8个字符以内
<3>字符集用默认的ZHS16GBK
3,Oracle中的数据类型
ORACLE中字段的数据类型
字符型
char 最大2000个字节 定长
char(10) '张三' 后添空格6个把10个字节补满 '张三 '
char(2) '男'
varchar2 最大4000个字节 变长
varchar2(10) '张三' 在数据库中'张三'
大对象 字符型大对象 >4000字节 最大4G
CLOB (Character Large OBject)
数字 number 范围 10的-38次方 到10的38次方
可以表示小数 也可以表示整数
number(4) 最大表示4位整数 -9999 到 9999
number(5,2) 表示5位有效数字 2位小数的 一个小数 -999.99 到 999.99
日期 date 包含年月日和时分秒 7个字节
图片 blob 二进制大对象 图像/声音 4G
4,如何建表,以及相关操作。
学生表student
create table student( --学生表
xh number(4), --学号
xm varchar2(10), --姓名
sex char(2), --性别
birthday date, --日期
sal number(7,2) --奖学金
);
班级class
create table class( --班级表
classid number(2), --班级编号
cname varchar2(20) --班级名字
);
添加字段(学生所在班级classid)
alter table student add (classid number(2));
修改字段的长度
alter table student modify (xm varchar2(12)) ;
修改字段的类型(不能有记录的)
alter table student modify (xh varchar2(5));
删除一个字段
alter table student drop column sal;
删除表
drop table student;
表的名字修改
rename student to stu;
字段如何改名字
--先删除
a)alter table student drop column sal;
--再添加
b)alter table student add (salary number(7,2));
如何插入数据
插入数据 insert语句
所有字段都插入
insert into student values ('A001','张三','男','01-5月-05',10);
ORACLE中默认的日期格式'DD-MON-YY' dd 日子(天) mon 月份 yy 2位的年
'09-6月-99' 1999年6月9号
改日期的默认格式
alter session set nls_date_format = 'yyyy-mm-dd';
insert into student values ('A002','MIKE','男','1905-05-06',10);
恢复ORACLE默认格式
alter session set nls_date_format = 'dd-mon-yy';
察看日期的格式
set linesize 1000
select * from nls_session_parameters
where parameter='NLS_DATE_FORMAT';
永久设置日期格式
改注册表oracle/HOME0 加字符串NLS_DATE_FORMAT 值yyyy-mm-dd
部分字段插入
insert into student(xh,xm,sex) values ('A003','JOHN','女');
插入空值
insert into student(xh,xm,sex,birthday) values ('A004','MARTIN','男',null);
修改 update
改一个字段
update student set sex='女' where xh='A001';
改多个字段
update student set sex='男',
birthday='1980-04-01'
where xh='A001';
改为空值 (修改为空时=null)
update student set birthday=null where xh='A001';
把生日为空的人的班级编号改为20(条件中的空是is null / is not null)
update student set classid=20 where birthday is null;
错误的没有达到要求
update student set classid=20
where birthday=null;
不表示空值 表示xm是null的字符串
update student set classid=20 where xm='null';
删除 delete
delete from student; 删除所有记录,表结构还在,写日志,可以恢复的,速度慢
drop table student; 删除表的结构和数据
delete from student where xh='A001'; 删除一条记录
truncate table student; 删除表中的所有记录,表结构还在,不写日志,无法找回删除的记录,速度快
查询 select
select * from student;
select xh,xm,sex from student;
select * from student where xh like 'A%1'; %任意多个字符
select * from student where xh like 'A__1'; _1个字符
select * from student where xh like '%A%'; select * from student where xh like 'A%';
select * from student where xh like '%A';
select * from student where xh = 'A%';
select * from student
order by birthday ; 升序 (order by birthday asc;)
select * from student
order by birthday desc; --降序
select * from student
order by birthday desc,xh asc; --按birthday 降序 按xh升序(asc/默认)
select * from student
where sex='女' or birthday='1999-02-01';
select * from student
where sex='女' and birthday='1999-02-01';
select * from student
where salary > 20 and xh <> 'B002'; (!=)
ORALCE的函数
单行函数 返回值只有一个
分组函数 返回值是多条记录
group by
sum
avg
单行函数
字符函数
concat 连接 ||
<1>显示dname和loc中间用-分隔
select deptno,dname||'----'||loc from dept;
dual哑元表 没有表需要查询的时候 可以用它
select 'Hello World' from dual;
select 1+1 from dual;
查询系统时间
select sysdate from dual;
<2> initcap 首字母大写
select ename,initcap(ename) from emp;
<3> lower 转换为小写字符
select ename,lower(ename) from emp;
<4> upper 转换为大写
update dept set loc=lower(loc);
update dept set loc=upper(loc);
<5> LPAD 左填充
select deptno,lpad(dname,10,' '),loc from dept;
<6> RPAD 右填充
<7> LTRIM 去除左边的空格
RTRIM 去除右边的空格
ALLTRIM 去除两边的空格
<8>replace 替换
translate 转换
select ename,replace(ename,'S','s') from emp;
用's'去替换ename中的'S'
select ename,translate(ename,'S','a') from emp;
<9> ASCII 求ASC码
chr asc码变字符
select ascii('A') from dual;
select chr(97) from dual;
select 'Hello'||chr(9)||'World' from dual;
'\t' ascii码是 9
'\n' ascii码是 10
select 'Hello'||'\t'||'World' from dual;
<10> substr 字符截取函数
select ename,substr(ename,1,3) from emp;
从第1个位置开始 显示3个字符
select ename,substr(ename,4) from emp;
从第4个位置开始显示后面所有的字符
<11> instr 测试字符串出现的位置
select ename,instr(ename,'S') from emp;
'S'第1次出现的位置
select ename,instr(ename,'T',1,2) from emp;
从第1个位置开始 测试'T'第2次出现的位置
<12> length 字符串的长度
select ename,length(ename) from emp;
日期和 时间函数
<1> sysdate 系统时间
select sysdate from dual;
select to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') from dual;
select to_char(sysdate,'DDD') from dual
select to_char(sysdate,'D') from dual
select to_char(sysdate,'DAY') from dual
select to_char(sysdate,'yyyy-mm-dd') from dual;
select to_char(sysdate,'yyyy"年"mm"月"dd"日" hh24:mi:ss') from dual;
select '''' from dual;
select to_char(sysdate,'SSSSS') from dual;
--从今天零点以后的秒数
<2> ADD_MONTHS 添加月份 得到一个新的日期
select add_months(sysdate,1) from dual;
select add_months(sysdate,-1) from dual;
select trunc(sysdate)-to_date('20050101','yyyymmdd') from dual;
select add_months(sysdate,12) from dual;
一年以后的今天
select add_months(sysdate,-12) from dual;
一年以前的今天
trunc(sysdate) 截取年月日
select sysdate+2 from dual;
数字代表的是天数
两个日期之间的差值代表天数
<3> last_day 某月的最后一天
select last_day(sysdate) from dual;
select add_months(last_day(sysdate)+3,-1) from dual;
本月第3天的日期
<4> months_between 两个日期之间的月数
select months_between(sysdate,'2005-02-01') from dual;
方向 sysdate - '2005-02-01'
select months_between('2005-02-01',sysdate) from dual;
转换函数
to_char 把日期或数字类型变为字符串
select to_char(sysdate,'hh24:mi:ss') from dual;
select to_char(sysdate,'yyyymmdd hh24:mi:ss') from dual;
select sal,to_char(sal,'L9,999') from emp;
L本地货币
to_number 把字符串变成数字
select to_number('19990801') from dual;
to_date 把字符串变成日期
select to_date('19800101','yyyymmdd') from dual;
select to_char(to_date('19800101','yyyymmdd'),
'yyyy"年"mm"月"dd"日"') from dual;
数学函数
ceil(x) 不小于x的最小整数
ceil(12.4) 13
ceil(-12.4) -12
floor(x) 不大于x的最大整数
floor(12.5) 12
floor(-12.4) -13
round(x) 四舍五入
round(12.5) 13
round(12.456,2) 12.46
trunc(x) 舍去尾数
trunc(12.5) 12
trunc(12.456,2) 12.45
舍去日期的小时部分
select to_char(trunc(sysdate),'yyyymmdd hh24:mi:ss') from dual;
mod(x,n) x除以n以后的余数
mod(5,2) 1
mod(4,2) 0
power(x,y) x的y次方
select power(3,3) from dual;
混合函数
求最大值
select greatest(100,90,80,101,01,19) from dual;
求最小值
select least(100,0,-9,10) from dual;
空值转换函数 nvl(comm,0) 字段为空值 那么就返回0 否则返回本身
select comm,nvl(comm,0) from emp;
comm 类型和 值的类型是 一致的
复杂的函数
decode 选择结构 (if ... elseif .... elesif ... else结构)
要求:
sal=800 显示低工资
sal=3000 正常工资
sal=5000 高工资
只能做等值比较
select sal,decode(sal,800,'低工资',3000,'正常工资',5000,'高工资','没判断')
from emp;
表示如下的if else 结构
if sal=800 then
'低工资'
else if sal =3000 then
'正常工资'
else if sal = 5000 then
'高工资'
else
'没判断'
end if
sal > 800 sal -800 > 0
判断正负
sign(x) x是正 1
x是负 -1
x是0 0
select sign(-5) from dual;
如何做大于小于的比较????
sal<1000 显示低工资 sal-1000<0 sign(sal-1000) = -1
1000<=sal<=3000 正常工资
3000<sal<=5000 高工资
select sal,decode(
sign(sal-1000),-1,'低工资',
decode(sign(sal-3000),-1,'正常工资',
0,'正常工资',1,
decode(sign(sal-5000),-1,'高工资','高工资')
)) as 工资状态 from emp;
一般的情况 decode(x,y1,z1,y2,z2,z3)
if x= y1 then
z1
else if x = y2 then
z2
else
z3
end if
分组函数 返回值是多条记录 或计算后的结果
group by
sum
avg
<1> 计算记录的条数 count
select count(*) from emp;
select count(1) from emp;
select count(comm) from emp; 字段上count 会忽略空值
comm不为空值的记录的条数
统计emp表中不同工作的个数 ????
select count(distinct job) from emp;
select distinct job from emp;
select distinct job,empno from emp;
select job,empno from emp;
得到的效果是一样的,distinct 是消去重复行
不是消去重复的列
<2>group by 分组统计
--在没有分组函数的时候
--相当于distinct 的功能
select job from emp group by job;
select distinct job from emp;
--有分组函数的时候
--分组统计的功能
统计每种工作的工资总额是多少??
select job,sum(sal) from emp
group by job; --行之间的数据相加
select sum(sal) from emp; --公司的工资总额
统计每种工作的平均工资是多少??
select job,avg(sal) from emp
group by job;
select avg(saL) from emp; --整个公司的平均工资
显示平均工资>2000的工作???
<1>统计每种工作的平均工资是多少
<2>塞选出平均工资>2000的工作
从分组的结果中筛选 having
select job,avg(sal) from emp
group by job
having avg(sal) > 2000;
group by 经常和having搭配来筛选
计算工资在2000以上的各种工作的平均工资????
select job,avg(sal) from emp
where sal > 2000
group by job
having avg(sal) > 3000;
一般group by 和 having搭配
表示对分组后的结果的筛选
where子句 --- 用于对表中数据的筛选
<3> max min
select max(sal) from emp;
公司的最高工资
select min(sal) from emp ;
公司的最低工资
找每个部门的最高和最低的工资??
select deptno,max(sal),min(sal) from emp
group by deptno;
找每个工作的最高和最低的工资??
select job,max(sal),min(sal) from emp
group by job;
找每个部门中每种工作的最高和最低的工资??
select deptno,job,max(sal),min(sal)
from emp
group by deptno,job;
select max(sal),min(sal)
from emp
group by deptno,job;
单个字段如果没有被分组函数所包含,
而其他字段又是分组函数的话
一定要把这个字段放到group by中去
<4>关联查询
多张表,而表与表之间是有联系的
是通过字段中的数据的内在联系来发生
而不是靠相同的字段名来联系的或者是否有主外键的联系是没有关系的
select dname,ename from emp,dept;
笛卡尔积 (无意义的)
--当2个表作关联查询的时候一定要写关联的条件
--N个表 关联条件一定有N-1个
select dname,ename from mydept,myemp
where mydept.no = myemp.deptno;
多表查询的时候一定要有关联的条件
--使用的表的全名
select dname,ename from emp,dept
where emp.deptno = dept.deptno ;
--使用表的别名
select dname,ename,a.deptno from emp a,dept b
where a.deptno = b.deptno and a.deptno = 10;
--等值连接(内连接-两个表的数据作匹配a.deptno = b.deptno )
select dname,ename,a.deptno from
emp a inner join dept b
on a.deptno = b.deptno;
where a.deptno = 10;
--on写连接条件的
--where中写别的条件
--使用where/on
select dname,ename,a.deptno from emp a,dept b
where a.deptno = b.deptno and a.deptno=10;
--on中写连接条件
--where中写其他的条件
select dname,ename,a.deptno from
emp a inner join dept b
on a.deptno = b.deptno
where a.deptno = 10 ;
--外连接
左外连接 右外连接 全外连接
(+)写法只有在ORACLE中有效
select dname,ename,b.deptno
from emp a,dept b
where a.deptno(+) = b.deptno;
--标准写法
select dname,ename,b.deptno
from emp a right outer join dept b
on a.deptno = b.deptno;
select dname,ename,b.deptno
from emp a,dept b
where a.deptno = b.deptno(+);
--标准写法
select dname,ename,b.deptno
from emp a left outer join dept b
on a.deptno = b.deptno;
--标准写法(全外联)
select dname,ename,b.deptno
from emp a full outer join dept b
on a.deptno = b.deptno;
--自连接
select a.ename as 员工姓名,b.ename as 经理名字 from emp a,emp b
where a.mgr = b.empno(+);
a.empno = b.mgr ???????
<5>子查询
在select语句中嵌套了另一个select语句
1)where 子句中嵌套子查询
2)用子查询的结果 作为字段来出现
--1)where 子句中嵌套子查询,执行顺序是
先执行子查询 再执行主查询
找出工资高于公司平均工资的所有员工??
select * from emp where sal+nvl(comm,0) > (select avg(sal+nvl(comm,0)) from emp);
高于部门30中员工最高工资的其他员工???
select * from emp where sal+nvl(comm,0) > all (select sal+nvl(comm,0) from emp
where deptno = 30);
低于部门30中员工工资的其他员工???
select * from emp where sal+nvl(comm,0) < all (select sal+nvl(comm,0) from emp
where deptno = 30);
select * from emp where sal+nvl(comm,0) < any (select sal+nvl(comm,0) from emp
where deptno = 30);
--2)用子查询的结果 作为字段来出现
先执行主查询 再执行子查询
<1>找员工姓名和直接上级的名字
select ename as 员工姓名,(select ename from emp where empno = a.mgr) as 经理姓名
from emp a;
<2>显示部门名称和人数
select dname,(select count(*) from emp where deptno=a.deptno) as rs from dept a;
<3>显示每个部门的最高工资的员工
select * from emp a where (deptno, sal) in ( select deptno,max(sal) from emp group by deptno);
select a.* from emp a,( select deptno,max(sal) as msal from emp group by deptno) c where a.deptno = c.deptno and
a.sal = c.msal;
--最大值和最小值的比较 转化为人数的比较
select * from emp a where (select count(*) from
emp where deptno = a.deptno and
sal > a.sal) = 0 and a.deptno is not null;
<4>显示每个部门的工资前2名的员工
select * from emp a where (select count(*) from
emp where deptno = a.deptno and
sal > a.sal) <=1 and a.deptno is not null;
<6> 层次查询
--level 伪列 层次查询的时候可以使用的 层的编号
select lpad('+',level,' ')||ename from emp
connect by prior empno = mgr --父子关系 父结点中的empno = 子节点中的mgr
start with mgr is null;--从 mgr is null的节点 开始遍历
select lpad('+',level,' ')||ename from emp
connect by prior empno = mgr
start with ename = 'BLAKE';
<7> TOP 前几行 (sqlserver)
rownum (oracle伪列)
--emp表的前2行
--rownum必须使用<=的关系比较运算符
select * from emp where rownum <= 2;
select top 2 * from emp; --sqlserver的写法
select * from emp where rownum = 1;
--公司工资最高的2个人
/*select * from emp
where rownum <= 2
order by sal desc;*/ 错误的
select * from (select * from emp order by sal desc)
where rownum <= 2;
--分页查询
--每页显示4行 一共有14行记录
第1页 第1-4行
第2页 第5-8行
第3页 第9-12行
第4页 第13-14行
--希望每次页面显示的时候 都只查询回需要的记录
select * from (select rownum as num,emp.* from emp)
where num >= 9 and num <= 12;
select * from (select rownum as num,emp.* from emp)
where num >= 13 and num <= 14;
<例子>
建立表如下:
学生基本信息表
CREATE Student(
[Studentid][Int]IDENTITY(1,1)NOT NULL primary key,--主键
[StudentName][char]NOT NULL
)
课程信息表
CREATE Subject(
[SubjectID][char]NOT NULL primary key, --主键
[SubjectName][char]NOT NULL
)
成绩表
CREATE Grade(
[Studentid][Int]NOT NULL, --联合主键
[SubjectID][char]NOT NULL, --联合主键
[Grade] [INT]NOT NULL,
primary key (studentid,subjectid)
)
1.将建表命令改为ORACLE语句在ORACLE中建表
create table student( --学生表
studentid number(3) primary key, --学生编号
studentname varchar2(20) --学生的姓名
);
create table subject( --课程表
subjectid char(3) primary key, --课程编号
subjectname varchar2(20) --课程的名字
);
create table grade( --分数表
studentid number(3) references student(studentid), --学生id
subjectid char(3) references subject(subjectid), --课程id
mark number(3), --分数
primary key (studentid,subjectid) --联合主键
);
insert into student values (101,'张三');
insert into student values (102,'李云');
insert into student values (103,'未');
insert into subject values ('A01','C++');
insert into subject values ('A02','ASP');
insert into subject values ('A03','JAVA');
insert into grade values (101,'A01',59);
insert into grade values (101,'A02',72);
insert into grade values (101,'A03',90);
insert into grade values (102,'A01',75);
insert into grade values (102,'A02',91);
insert into grade values (103,'A01',71);
2.作如下4题
第一问:查询出以下信息
学号 学生姓名 课程名称 成绩 (要全部学生信息)
关联查询 (多张表的)
别名
select a.studentid as "学 号",studentname "学生姓名",
subjectname "课程名称",mark "成 绩"
from student a , subject b , grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid;
[select a.studentid "学 号",studentname "学生姓名",
subjectname "课程名称",mark "成 绩"
from student a , subject b , grade c] 笛卡尔积
3 * 3 * 6 = 54;
第二问:查询出以下信息
学号 学生姓名 课程名称 成绩(只显示每科最高分)
select a.studentid "学 号",studentname "学生姓名",
subjectname "课程名称",mark "成 绩"
from student a,subject b,grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid
and (subjectname,mark)
in (select subjectname "课程名称",max(mark) "成 绩"
from student a,subject b,grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid
group by subjectname)
(最高分---分数比我高的学生的人数=0)
select a.studentid "学 号",studentname "学生姓名",
subjectname "课程名称",mark "成 绩"
from student a,subject b,grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid
and (select count(*) from grade
where subjectid = b.subjectid and
mark > c.mark) = 0
第三问:查询出以下信息
学号 学生姓名 课程名称 成绩 (成绩大于60时的显示及格,小于60时的显示不及格)
select a.studentid "学 号",studentname "学生姓名",
subjectname "课程名称",
decode(sign(mark-60),-1,'不及格','及格') "成 绩"
from student a,subject b,grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid
第四问:查询出以下信息
学号 学生姓名 (查询出课程超过1门以上学生的信息)
select a.studentid "学 号",studentname "学生姓名",
count(subjectname)
from student a , subject b , grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid
group by a.studentid,studentname
having count(subjectname) >= 2
-- select * from emp where rownum > 2; 错误的
删除:
在硬盘上的一个隐含安装的目录Programm Files下的ORACLE
一、开始前的准备
1.启动Oracle
启动监听服务:OracleOraHome90TNSListener
启动实例服务:OracleServiceOrac
2.Oracle系统用户
Oracle三大系统用户
默认用:system/welcome
超级用户:sys/welcome 权限最大
普通用户:scott/tiger
3.登录Oracle的方式
Windows窗口下的sqlplus的操作 运行->sqlplusw.exe
DOS下的sqlplus的操作 运行-> sqlplus.exe
登录Oracle但不连接数据库 运行->sqlplusw /nolog
connect 用户名/密码@主机连接字符串 连接到指定用户
4.Oracle常用操作
show user 查看当前用户 select * from tab where tabtype='TABLE' 查看当前用户下的表
desc dept 察看表dept的结构
quit/exit 退出
clear screen 清除屏幕
set linesize 200 设置一行显示200个字符
set pagesize 20 设置每页显示20行
spool 文件名 (spool c:\abc.txt) 作日志文件命令 spool off
alter session set nls_date_format = 'yyyy-mm-dd'; 改日期的默认格式
conn /as sysdba select * from v$version;查看当前Oracle的版本
conn system/welcome select * from v$tablespace; 查看表空间
5.表空间 用户 表三者的关系
一个用户可以使用一个或多个表空间,一个表空间也可以供多个用户使用
用户和表空间没有隶属关系。
表空是一个用来管理数据存储逻辑概念,表空间只是和数据文件发生关系,数据文件是物理的,
一个表空间可以包含多个数据文件,而一个数据文件只能隶属一个表空间
二、常规操作
1.DDL语句(数据定义语言) Data Define Language
create alter drop truncate 开头的语句 truncate table <表名>
特点:<1>建立和修改数据对象
<2>建立和修改直接存入库中,直接生效
创建表空间:Create tablespace Product datafile 'D:\test\aa.DBF' size 100M
删除表空间:Drop tablespace Product
创建用户: Create user zhangsan identified by "welcome" default tablespace Product
修改用户: Alter user zhangsan identified by "Hello"
授予用户连接的权限: grant connect to zhangsan;
撤销用户连接权限: revoke connect from zhangsan;
授予用户在表空间创建对象的权限
grant unlimited tablespace to zhangsan;
grant resource to zhangsan;
系统特权:unlimited tablespace表示用户可以在任意表空间中创建对象,且此权限只能授予用户而不能授予角色
resource角色:给用户RESOUCE权限后,用户就拥有在所有表空间上建表权限
授予用户zhangsan对Emp表增、删、查、改的权限
grant select on scott.empa to y2;
delete
update
insert
all (=select,delete,update,insert)
with grant option 授予用户权限,则接受权限的用户可以将此权限授予其他用户.
(1).建表,并指定表空间
示例: Create table tab1
(
no number(4),
name varchar2(10)
)tablespace Product;
学生表 Student
Create table student
(
xh number(4) primary key, --学号
name varchar2(10) not null, --姓名
sex char(2) check (sex in ('男','女')),--性别
birthday date,--生日
sal number(7,2), --奖学金
classid number(2) references class(classid) --班级
); 班级表class
Create table class
(
classid number(2), --班级编号
cname varchar2(20) --班级名字
);
外键引用的列一定是主键或有unique约束的列
drop table student; 删除表的结构和数据
delete from student; 只删除数据,速度慢,数据可以恢复
truncate table student; 删除记录的 速度快 数据不能恢复
添加字段(学生所在班级classid)
alter table student add (classid number(2));
修改字段的长度
alter table student modify (xm varchar2(12)) ;
修改字段的类型(不能有记录的)
alter table student modify (xh varchar2(5));
删除一个字段
alter table student drop column sal;
删除表
drop table student;
表的名字修改
rename student to stu;
字段如何改名字
--先删除
a)alter table student drop column sal;
--再添加
b)alter table student add (salary number(7,2));
Number数据类型的存储范围
精度 存储字节数
1 - 9 5
10-19 9
20-28 13
29-38 17
Oracle数据操作语言 DML
接上一篇:
2. DML语句(数据操作语言) Data Manupilate Language
select
insert
delete
update
特点:<1>对数据起作用的
<2> 这些语句的修改是在内存中发生的
要想改动存入库中必须要commit语句
查看当前用户的所有权限
select * from session_privs;
查看当前用户下的所有表
select * from tab where tabtype='TABLE';
3. TCL(事务控制语句) Transaction Control Language
commit; 提交 修改保存到数据库中
rollback; 回滚 取消内存中的改动
savepoint;保存点 分解事务的 把事务变小
DDL语句 会自动提交以前未提交的事务
关闭SQLplus工具 也会自动提交未提交的事务的
事务 -- 就是一个完整的对数据的DML操作
所有事务 都是要明确的提交和回滚的
--转账
update 账目表
set 钱=钱-500
where 帐号='A';
update 账目表
set 钱=钱+500
where 帐号='B';
commit;
事务何时存在 DML语句中除select以外都会有事务
《《《《《《《注意》》》》》 / 重复运行上一条SQL语句
commit; 结束上一个事务 并且开始一个新的事务
update student set sal = null where xh =1000;
savepoint c111;
insert into student(xh,name,sex) values (1004,'MIKE','男');
rollback to c111; --撤销了插入的数据
rollback; --从c111这个点回滚到事务的开始点
《SQLPLUS规则》
a)DML语句后跟上DDL语句 DML语句的事务会被自动提交
b)exit/quit命令 退出 SQLPLUS环境时也会自动提交事务
点小叉子关闭sqlplus窗口 事务都自动回滚了
c)非法操作是不能提交事务的 ,只能导致事务回滚
《4》 DCL语句(数据控制语句) Data Control Language grant 授予权限
revoke 撤销权限
权限 select ,insert,delete,update
all (select ,insert,delete,update 总和)
角色 connect (登陆数据库),resource(建立表和对象)
如何建一个自己的用户?
必须是超级用户才能建用户
--连接到超级用户
connect system/manager
--建立用户名zhangsan 密码m123
create user zhangsan identified by m123;
--授予必要的权限connect 你能够连接
resource 你能建表不受空间的限制,建立对象
grant connect,resource to zhangsan;
--这个普通用户就建好了 和scott用户的权限是一样的
grant DBA to zhangsan; --张三的权限和System一样
--改张三的密码
<<1>> 自己改自己的密码
connect zhangsan/m123
密码改为了mm1
alter user zhangsan identified by mm1;
<<2>> 超级用户来改
connect system/manager
alter user zhangsan identified by mm1;
继续上一篇:
给表添加约束
主键约束 -- 每个表要有主键,唯一的标识一行数据
非空约束
唯一性约束
外键约束
检查约束
查看一个表的约束:
select constraint_name,constraint_type
from user_constraints
where table_name = '表名'
查看约束作用于那个字段:
select * from user_cons_columns
where CONSTRAINT_NAME='约束名;
1.建立表的同时使用约束
create table student( --学生表
xh number(4) primary key, --学号主键
xm varchar2(10) not null, --姓名不能为空
sex char(2) check (sex in ('男','女')), --性别
birthday date unique, --日期
sal number(7,2) check (sal between 500 and 1000),--奖学金 sal >=500 and sal <=1000
classid number(2) references cla(id)
); --必须要先有cla表才对
--一定先建立班级cla表
2.建立约束的同时给约束指定名字,便于删除
create table stu( --学生表
xh number(4) constraint pk_stu primary key, --学号是主键
xm varchar2(20) constraint nn_stu not null, --姓名非空
age number(2) constraint ck_stu check (age between 10 and 90),
birthday date,
shenfenzheng number(18) constraint uq_stu unique, --身份证唯一
classid number(2) constraint fk_stu references cla(id) -- 班级编号外键
--(引用的一定是另外表的主键或唯一性约束的字段)
);
3.建完表后加约束
添加主键约束:alter table student add constraint pk_stu primary key (xh);
添加非空约束:alter table student modify (xm not null);
检查约束:
alter table student add check(sex in ('男','女'));
alter table student add constraint ck_sal check(sal between 500 and 1000));
添加外键约束: alter table student add constraint fk_stu foreign key (classid) references cla(id);
添加唯一约束: alter table student add constraint uq_sfz unique(shenfenzheng);
4.删除约束:
格式:alter table 表名 drop constraint 约束名
alter table student drop constraint fk_stu;
SQL函数
单行函数: 返回值只有1个,可以出现在Select字句或Where字句中
分组函数: 返回值是多条记录
一。单行函数:
1.ASCII
返回与指定的字符对应的十进制数;
SQL> select ascii('A') A,ascii('a') a,ascii('0') zero,ascii(' ') space from dual;
A A ZERO SPACE
--------- --------- --------- ---------
65 97 48 32
2.CHR
给出整数,返回对应的字符;
SQL> select chr(54740) zhao,chr(65) chr65 from dual;
ZH C
-- -
赵 A
3.CONCAT
连接两个字符串;
SQL> select concat('010-','88888888')||'转23' 高乾竞电话 from dual;
高乾竞电话
----------------
010-88888888转23
4.INITCAP
返回字符串并将字符串的第一个字母变为大写;
SQL> select initcap('smith') upp from dual;
UPP
-----
Smith
5.INSTR(C1,C2,I,J)
在一个字符串中搜索指定的字符,返回发现指定的字符的位置;
C1 被搜索的字符串
C2 希望搜索的字符串
I 搜索的开始位置,默认为1
J 出现的位置,默认为1
SQL> select instr('oracle traning','ra',1,2) instring from dual;
INSTRING
---------
9
6.length 返回字符串的长度;
7.LOWER 返回字符串,并将所有的字符小写
8.UPPER 返回字符串,并将所有的字符大写
9.RPAD和LPAD(粘贴字符)
RPAD 在列的右边粘贴字符
LPAD 在列的左边粘贴字符
SQL> select lpad(rpad('gao',10,'*'),17,'*')from dual;
LPAD(RPAD('GAO',1
-----------------
*******gao*******
不够字符则用*来填满
10.LTRIM和RTRIM
LTRIM(字符串,值) 删除字符串左边指定的值
RTRIM(字符串,值) 删除字符串右边指定的值
11.SUBSTR(string,start,count)
取子字符串,从start开始,取count个
12.REPLACE('string','s1','s2')
string 希望被替换的字符或变量
s1 被替换的字符串
s2 要替换的字符串
13.SOUNDEX
返回一个与给定的字符串读音相同的字符串
SQL> create table table1(xm varchar(8));
SQL> insert into table1 values('weather');
SQL> insert into table1 values('wether');
SQL> insert into table1 values('gao');
SQL> select xm from table1 where soundex(xm)=soundex('weather');
XM
--------
weather
wether
14.ROUND和TRUNC
按照指定的精度进行舍入
SQL> select round(55.5),round(-55.4),trunc(55.5),trunc(-55.5) from dual;
ROUND(55.5) ROUND(-55.4) TRUNC(55.5) TRUNC(-55.5)
----------- ------------ ----------- ------------
56 -55 55 -55
15.Least('表达式1','表达式2','表达式3') 返回一组表达式中的最小值
16.TO_NUMBER 将给出的字符转换为数字
17.TO_DATE(string,'format') 将字符串转化为ORACLE中的一个日期
18.NEXT_DAY(date,'day') 给出日期date和星期x之后计算下一个星期的日期
19..MONTHS_BETWEEN(date2,date1) 两个日期相差的天数
20.Decode(字段1,值1,结果1,值2,结果2...,默认值)
21.nvl(表达式1,表达式2) 表达式1为NULL,返回表达式2;不为NULL,返回表达式1。注意两者的类型要一致
22.nvl2(a,b,c)
表达式1不为NULL,返回表达式2;
为NULL .返回表达式3。表达式2和表达式3类型不同的话,表达式3会转换为表达式2的类型
23.nullif (expr1, expr2) ->相等返回NULL,不等返回expr1
分组函数
AVG([{DISYINCT|ALL}]) distinct去掉重复的数据 all所有数据
Max
SUM
Count 计数函数
count(*) 统计所有的行,包括重复的值和空值
count(col_name) 统计列中非空值的个数
count(distinct col_name) 统计列中除去空值和重复值的行数
分析函数:
作用:用于完成对聚集的累计排名,移动平均数和报表计算。
分析函数是查询中执行的最后一组操作,只能出现在select列表或order by 字句
row_number() over([Partition by column] order by column) 返回唯一排序值select
按工资排名:
ename,job,deptno,sal,row_number() over(order by sal desc) as A from empa;
按部门分组再按工资排名
select ename,job,deptno,sal,row_number() over(Partition by deptno order by sal desc) as A from empa
rank() 计算一个值在一组值中的排位,排位从1开始,相等值的行排位相同,序数跳跃相应值.
select ename,sal,comm,deptno,rank() over(partition by deptno order by sal desc) from empa;
dense_rank() 计算一个行在一组有序行中的排位,排位从1开头的连续整数,具有相等值,排位相同。排位是连续的。
select d.dname,e.ename,e.sal,dense_rank() over(partition by e.deptno order by e.sal desc) denserank
from empa a,dept d where e.deptno=d.deptno
继续上一篇
1. 序列
查询当前用户下的序列:select * from user_sequences
定义:用来生成唯一、连续的整数的数据库对象,序列通常用来自动生成主键或唯一键的值、可升、可降序排列.
语法: Create sequence 序列名称 //从1开始 每次自动增加1 没有最大值
[star with 值] 指定要生成的第一个序列号,对于升序默认值为最小值、反之...
[increment by 值] 间隔数
[maxvalue 值|nomaxvalue] 序列最大值,如果指定为nomaxvalue,则升序最大值为10的27次方,降序-1.
[minvalue 值|nominvalue] 序列最小值,-----------------------升序为1,降序为10的负26次方
[cycle|nocycle] cycle指序列到达最大或最小时,将从头开始生成值 nocycle值不在生成
[cache 值|nocache] 预先分配一组序列号,将其保存在内存中. 默认缓存20个序列
访问序列方法: currval 和nextval --当前序列 select 序列名.currval from dual
更改序列:Alter sequence 序列名
删除序列:drop sequence 序列名
注意-------------序列使用时需要先用nextval输出完以后再来使用
使用:
1.和表关联作为表的字段的值
a) create table student(
xh number(4) primary key, --学号
xm varchar2(20) not null --姓名
);
要求:学号字段 从1000开始每次增加4 最大值9999
--建立序列
create sequence xh_seq
start with 1000 --从1000开始
increment by 4 --每次增加4
maxvalue 9999 --最大值 9999
;
--使用SQL语句关联
insert into student values
(xh_seq.nextval,'Mike');
insert into student values
(xh_seq.nextval,'John');
insert into student values
(xh_seq.nextval,'Rose');
--特点:能产生唯一的值,但是不能保证值在表中的连续性
b) create table teacher(
teacherxh varchar2(10) primary key,
teachername varchar2(20)
);
要求:教师的编号的格式是TH00001
TH00002
....
--建立序列
create sequence teacher_seq
maxvalue 99999;
--
insert into teacher values ('TH'||
ltrim(to_char(teacher_seq.nextval,'00000')),
'张三');
insert into teacher values ('TH'||
ltrim(to_char(teacher_seq.nextval,'00000')),
'李');
insert into teacher values ('TH'||
ltrim(to_char(teacher_seq.nextval,'00000')),
'王');
2.视图
查看当前用户下的视图:select view_name from user_views;
作用:隐藏数据,增加系统的安全性
语法:Create [or replace] [Force|noForce] veiw 视图名 [(别名1,别名2...)]
AS 子查询
[with check option [constraint 约束名]]
[with read only] 视图是只读的
其中:or replace 表示替代已经存在的视图
force 表示不管基表是否存在,创建视图
noforce 表示只有基表存在时,才创建视图.
别名是为子查询中选中的列新定义的名字,替代查询表中原有的列名。
with check option 对视图操作时必须满足子查询的约束条件。后面的约束名是该约束条件的名字
删除视图者需要是视图的建立者或者拥有DROP ANY VIEW权限。视图的删除不影响基表,不会丢失数据
对视图操作需满足以下条件:
<1>建立视图的select语句必须是简单的select语句
简单:不能是多表的查询
不能有分组函数
<2>建立视图的时候不能带with readonly关键字
例:
create or replace view emp_v2
as --select语句
select empno,ename,sal from emp
with read only; --只读视图
3.同义词
查看用户创建的同义词:select * from user_synonum;
定义:数据库对象的一个别名
用途:1.简化SQL
2.隐藏对象名称和所有者
3.为分布式数据库的远程对象提供了位置透明度
4.提供对象的公共访问
注意:使用同义词前需要确保用户得到访问同义词的权限
同义词分为:
1.私有同义词 --只能被当前用户模式访问 要在自身模式下创建须 Create synonum 权限
2.共有同义词 --须Create any synonym权限
语法: Create [or replace] [public] synonym 同义词名称 for 要创建同义词对象的名称
4.索引
作用:加快查询 索引一定是建立在表上的.
语法:Create Index 索引名 on 表名(列名)
创建唯一索引: Create unique Index 索引名 on 表名(列名)
创建位图索引: Create bitmap Index 索引名 on 表名(列名)
数据的不同值对于记录的行数来说 是个很小的数 这种字段适合使用位图索引 它比普通索引效率高
不能用索引的条件:
<1>规则1:索引的字段不能参与运算
<2>规则2:索引的字段上不能使用函数
5.簇
定义:用于多表联合查询,提高数据查询效率
1.簇的创建必须在创建表结构时指定
2.如果使用簇,则两个表必须要有主外键关系
簇的使用步骤:
1.创建簇 Create cluster 簇名称(字段名 数据类型);
2.创建主键表使用簇
Create table depa (
deptno number(2) primary key,
dname varchar2(20)
) cluster 簇名(deptno);
3.创建外键表使用簇
Create table empa(
empno number(4) primary key,
ename varchar2(20)
) cluster 簇名(empno)
4.在簇上建立索引
Create Index 索引名 on cluster 簇名
继续上篇的学习
Oracle性能对象
要点:分区必须是在创建表的结构时指定,分区方式一旦指定是不能改变的。
分区方式:
1 范围分区
2 散列分区
3复合分区
3列表分区
表分区的优点:
一、改善表的查询性能
二、表更容易管理,表的数据存储在多个部分,按分区加载和删除数据更快
三、便于备份和恢复
四、提高数据安全性
-----------注意:要分区的表不能具有Long和Long raw数据类型
范围分区:根据表的某个列或一组列的值范围,决定将数据存储在那个分区
create table niegc_part
(
part_id integer primary key,
part_date date,
part_dec varchar2(100)
)
partition by range(part_date)--根据日期分区
(
partition part_01 values less than(to_date('2006-01-01','yyyy-mm-dd')) tablespace dw1,
partition part_02 values less than(to_date('2007-01-01','yyyy-mm-dd')) tablespace dw2,
partition part_03 values less than(maxvalue) tablespace dw1
);
散列分区
散列分区通过指定分区编号来均匀分布数据的一种分区类型,因为通过在I/O设备上进行散列分区
,使行这些分区大小一致。如将part_id的数据根据自身的情况散列地存放在指定的二个表空间中:
create table niegc_part
(
part_id integer primary key,
part_date date,
part_dec varchar2(100)
)
partition by hash(part_id)
(
partition part_01 tablespace dw1,
partition part_02 tablespace dw2
);
--系统将按part_id将记录散列地插入二个分区中,这里也就是二个不同的表空间中。
复合分区:范围分区和散列分区的结合
--语法
partition by range(列1)
subpartition by hash(列2)
subpartition 分区数目 [tore in (表空间1,表空间2)]
(
partition part1 values less than (值1),
partition part2 values less than (maxvalue)
)
--例:对emp表的复合分区,先按薪资分再按部门分
partition by range(sal)
subpartition by hash(empno)
(
partition p1 values less than('1501')
(
subpartition sp1 tablespace a1,
subpartition sp2 tablespace a2
)
partition p2 values less than('3001')
(
subpartition sp3 tablespace a1,
subpartition sp4 tablespace a2
)
)
--查看表分区 select * from emp partition(p1)
select * from emp subpartition(sp1)
列表分区:允许用户明确地控制行到分区的映射
--语法
partition by list(列名)
(
partition part1 values(值1),
partition part2 values(值2),
partition part3 values(default)
--default关键字用于存储前面的分区不能存储的记录
)
分区的维护操作
1.添加分区
alter table Table add partition 分区名 values less than (值)
如果边界是maxvalue 使用split partition语句
alter table Table split partition 分区名 at (值)
2.删除分区
alter table Table drop partition 分区名
3.截断分区 (只删除记录,不删除结构)
alter table Table truncate partition 分区名
4.合并分区
alter table Table merge partitions p1,p2 into partition p2
5.拆分分区
alter table Table split partition 分区1 at (值) into(partition 分区1,partition 分区2)
6.移动分区
alter table Table move partition 分区 tablespace(表空间名)
继续上篇的学习
PL/SQL简介
PL/SQL(Procedural Language Sql,过程语言|SQL)是结合了Oracle过程语言和结构化查询语言(SQL)的一种扩展语言.
PL/SQL块是一段后台服务程序,它负责将数据从数据库中取出来,在PL/SQL块中进行处理,将处理的结果送到数据库.
优点:
1,支持SQL
2,支持面向对象编程(OOP)
3,更好的性能
4,可移置性
5,与SQL集成 --支持所有SQL数据类型和Null值 ,另%type %rowType属性类型更加强了这种集成
6,安全性
PL/SQL块包括3个部分:
1,声明部分 --变量,游标,自定义异常, 局部子程序
2,可执行部分 --执行命令,可嵌套子块
3,异常处理部分
1PL/SQL块
2 declare
3
4 begin
5 --SQL语句
6 --直接写的SQL语句(DML/TCL)
7 --间接写execute immediate <DDL/DCL命令字符串>
8 --select 语句
9 <1>必须带有into子句
10 select empno into eno from emp
11 where empno =7369;
12 <2>只能查到一行**********
13 <3>字段个数必须和变量的个数一致
14 exception --异常
15 when <异常名字> then --特定异常
16 <处理语句>
17 when others then --所有异常都可捕获
18 <处理语句>
19 end;
20
语言特征:
<1>,大小写不敏感
<2>,复合符号的含义
:= 赋值操作符 ||连接操作符 ..范围操作符 **求幂操作符 《,》标签分隔符 --单行注释 /*,*/多行注释
<3>声明变量 --变量名 数据类型 :=值 例: varA varchar2(10):='声明变量';
<4>声明常量 --变量名 constant 数据类型 := 值
---------------- 技巧:初始化变量和常量时,保留字default可替换:=赋值操作符--------------
<5>属性类型
%type --引用某个变量或数据库列的数据类型来声明变量
%rowType --提供表示表中一行的记录类型
<6>控制结构
a,条件控制 if then 或 if then else 或 if then elsif 或 case
b,循环控制 loop
while exit或exit when退出
for
c,顺序控制 Goto Null语句
语法示例:
1--PL/SQL 简单语法
2
3Begin
4 null;
5End;
6/
7
8Declare
9 varA number(4);
10Begin
11 varA := 1234;
12 DBMS_output.put_line(varA);
13End;
14/
15
16Declare
17 varA number(4);
18Begin
19 varA := 1234;
20 DBMS_output.put_line(varA);
21 Declare
22 varB number(4):=2234;
23 Begin
24 DBMS_output.put_line(varA);
25 DBMS_output.put_line(varB);
26 End;
27 DBMS_output.put_line(varB);
28End;
29/
30
31Declare
32 varA number(4);
33 varB number(4):=2234;
34Begin
35 varA := 1234;
36 DBMS_output.put_line(varA||' '||varB);
37End;
38/
39Begin块 注意事项:
40-- 数据定义语言不能直接执行
41Begin
42 drop table depta;
43End;
44/
45
46-- select不能直接执行
47select --必须使用select into 形式,只能且必须返回一行
48Declare
49 varE empa%rowType; --与表的一行类型一样
50 vno empa.empno%type; -- 与表的某列类型一样
51Begin
52 vno := 7902;
53 select * into varE from empa where empno = vno;
54 DBMS_output.put_line( varE.ename||' '||varE.job);
55End;
56/
57
58inset --可以直接执行
59Declare
60 vno empa.empno%type;
61 vna empa.ename%type;
62 vjob empa.job%type;
63Begin
64 vno := 1236;
65 vna := 'Wing';
66 vjob := 'MANAGER';
67 insert into empa (empno,ename,job) values(vno,vna,vjob);
68End;
69/
70
71delete --可以直接执行
72Declare
73 vno empa.empno%type;
74Begin
75 vno := 5555;
76 delete from empa where empno = vno;
77End;
78/
79
80
81update --可以直接执行
82Declare
83 vno empa.empno%type;
84 rsal empa.sal%type;
85Begin
86 vno := 1236;
87 rsal := 100;
88 update empa set sal = nvl(sal,0) + rsal where empno = vno;
89End;
90/
91
92 --事物控制语言可以直接执行
93Declare
94 vno empa.empno%type;
95 rsal empa.sal%type;
96Begin
97 vno := 1236;
98 rsal := 100;
99 update empa set sal = nvl(sal,0) + rsal where empno = vno;
100 commit;
101End;
102/
103
104 -- 数据安全语言(DCL)不能直接执行
105Begin
106 grant connect to scott;
107End;
108/
例子:
题:编写程序 向DEPT表中插入一条记录,
从键盘输入数据,如果
数据类型输入错误要有提示
无法插入记录 也要有提示
只能输入正数,如果有负数提示
declare
n number;
no dept.deptno%type;
nm dept.dname%type;
lc dept.loc%type;
exp exception; --用户定义的变量
exp1 exception; --用户定义的变量
num number:=0; --计数器
pragma exception_init(exp,-1); --预定义语句
--捆绑Oracle内置异常(-1错误和异常变量关联),-1 主键冲突
pragma exception_init(exp1,-1476);除零异常
e1 exception; --用户定义的变量
begin
--输入值
no := '&编号';
num := num + 1;
if no < 0 then
raise e1; --自定义异常的引发
end if;
nm := '&名称';
num := num +1;
lc := '&地址';
num := num +1;
n := 10 /0;
insert into dept values (no,nm,lc);
num := num +1;
commit;
exception
--自定义异常
when e1 then
dbms_output.put_line('编号不能为负数');
--数据类型不对
when value_error then
if num =0 then
dbms_output.put_line('编号数据类型不对');
elsif num = 1 then
dbms_output.put_line('名称数据类型不对');
elsif num =2 then
dbms_output.put_line('地址数据类型不对');
end if;
rollback;
--主键冲突
when exp then
--sqlcode全局变量 异常错误号
--sqlerrm全局变量 异常的文字信息
--dbms_output.put_line('异常的编号:'||sqlcode);
--dbms_output.put_line('异常的内容:'||sqlerrm);
--dbms_output.put_line('编号已存在') ;
rollback;
--非预定义异常(关联错误号)
when exp1 then
dbms_output.put_line('0做了除数') ;
raise_application_error(-20001,'0做了除数');
--引起一个自定义的错误
--预先保留-20001 到 -29999编号
rollback;
--其他的异常
when others then
dbms_output.put_line('异常的编号:'||sqlcode);
dbms_output.put_line('异常的内容:'||sqlerrm);
-- dbms_output.put_line('出现错误');
rollback;
end;