您的位置:首页 > 数据库 > Oracle

oracle数据库学习笔记

2020-07-28 16:04 1211 查看

一、基本信息及命令
1.Oracle数据库需要启动的服务:
OracleServiceSID(数据库名)主服务
OracleTnsListener 监听器
2.连接数据库:
1)SQLPlus
2)SQL Developer
3)PL/SQL Developer
3.SID:
4.数据库命令:
命令注释: –
显示当前用户:show 用户名
切换用户:connect 另一用户名
conn sys as sysdba
新建账户:
create user 用户名 identified by 口令
修改密码:
1)alter user 用户名 identified by 修改后的口令;
2)password 用户民
新口令;
解锁普通账户:
alter user 用户名 account unlock;
上锁:
alter user 用户名 account lock;
5.什么是数据库:
位于硬盘上,实际存在的文件,这些文件组织在一起,在逻辑上形成了一个整体。
简单说,硬盘上的文件的逻辑集合。

6.数据库的文件能否直接操作:
不能。使用实例来操作存储在硬盘上的文件。
实例的概念:位于内存中的数据结构,通过它用户可以读取数据库中的数据。
7.文件:
1)数据文件:保存的所有数据 *.dbf
2)日志文件:记录对数据库的操作 *.log
3)控制文件:记录数据库的物理结构,如数据库安装的位置,数据库名等 *.ctrl
4)配置文件:记录的是数据库的重要参数,如数据库的大小,内存结构 *.ora
8.继续命令:
查看数据库的名字和实例名:
Select * from 表名(系统表vdatabase)Selectinstancenamefromvdatabase) Select instance_name from vdatabase)Selectinstancen​amefromvinstance 实例名
用新账户登陆:
conn 用户名/密码
新用户登录被拒绝,没有权限

给新用户授权:
grant create session(会话) to 用户名;
建表授权:
grant create table to 用户名;
9.表空间
是一个逻辑的概念,里面包括所有的要创建的数据库的对象。如表,用户等。
表空间的划分: 数据块 数据区
表空间的含义:在操作中,我们新建的任何数据都是放在表空间上的。
Oracle中默认的表空间:system,users.
可以把自己新建的数据库对象,如表,视图等全部放入自己建立的表空间上,这样归类清楚,查询效率很高。
10.如何建立表空间:
语法:create tablespace 名字
datafile(表空间的位置) size(大小) autoextend 是否自动扩展
删除表空间
drop tablespace tb11 including contents and datafiles
列出当前用户的表空间:
select * from user_tablespaces
列出指定用户的表空间:

查看用户的默认表空间:
select username,default_tablespace from
dba_users
where username=”大写用户”;
查看你用户拥有的权限:
select * from
user_sys_privs
给用户赋予权限,有一个原则,不用直接给用户授权,先把要给的权限放入角色,然后把角色赋予用户即可。
新建用户,然后登录,并建表
1)connect角色:允许用户连接数据库
2)resource角色:允许用户创建数据库对象
3)dba角色:允许用户创建,删除,修改对象
删除用户:
drop user 用户名 cascade;
考察:查看有哪些用户:select * from dba_users
查看用户拥有的权限:select * from uer_sys_privs
查看用户拥有的角色:select * from user_role_privs
权限的分类:
1)系统权限:
包括:create alter drop
2)对象权限:CRUD 增删改查 select/insert/delete/update
赋予对象权限,让其他用户能够访问:grant select on 用户名.表名 to 本用户名
收回权限:revoke select on 用户名.表名 to本用户名
11.远程连接:
sqlplus 用户名/密码@ip/SID
12.如何创建新的数据库
dbca
13.如果管理员给用户一个查看table1的权限,那么这个用户可以把这个权限给其他用户:
grant select on system.表名 to 用户名 with grant(对象权限)/admin(系统权限) option.
14.查看授权者,被授权者:
select grantee,grantor,table_name from user_tab_privs_made;

15.数据类型:
1)字符类型:
char(字符固定长度)
varchar(可变长度2000)
nchar unicode编码
nvarchar
varchar2 4000
nvarchar2

2)数值类型:
int:整形
numeric(p,s) 精度
decimal(p,s)
number(p,s)
3)日期类型:
date(精准到秒)
timestamp(毫秒)
4)大对象:
二进制: raw 最大2G
lob: blob :二进制 4G
clob :字符
5)布尔:boolean
16.ddl和dml
Ddl:数据定义语言:create alter drop
Dml:数据操作语言:crud
二、高级操作
1.创建数据库对象:
Create table 表名
(
Id int,
sst1_name nvarchar2(40),
Sst1_age int
)
2.查看表结构
Des 表名
3.对表进行crud
1)添加数据:insert into 表名(字段)values(相应字段赋值);
2)查看数据:select * from 表名
3)删除数据:delete from 表名
4)更新数据:update 表名
Set 字段名=修改值
Where 条件
4.添加一个字段:
create table stu_3
(
Stu_id int,
Stu_name varchar2(20)
);

alter table stu_3 add stu_age int;

检查字段:desc stu_3(表名)
5. 修改字段:
age的类型修改为varchar
alter table 表名 modify 字段 varchar2(20)
6.删除字段:
alter table stu_3 drop column stu_age;
7.给表添加备注信息:
语法:comment on table 表名 is 备注信息
comment on table stu_3 is ‘学生表3’;
8.如何查看用户表的备注信息:
select * from user_tab_comments where table_name=’表名’;
9.给字段添加备注信息:
comment on column 表名.字段名 is ‘姓名’;
10. 查看字段备注:
select * from user_col_comments where table_name=’表名’;
11.给学生添加成绩字段,求出平均分
1)添加成绩:
alter table stu_3 add stu_score int;
2)添加成绩数据:
insert into stu_3(stu_id,stu_name,stu_score) values(1,’zhangsan’,88);
insert into stu_3(stu_id,stu_name,stu_score) values(2,’zhangsan’,66);
3)显示平均分:
添加平均分字段,在添加的同时,进行表达式计算,添加完毕后,数据显示。
alter table stu_3 add score_avg as (stu_score/2);
select * from stu_3
12.添加默认值:
为学生表添加入学时间,给这个字段添加一个默认值

添加入学时间:alter table stu_3 add recruit_time date;
添加默认值:alter table stu_3 modify recruit_time default sysdate; (当前系统时间)
注意:对于数据中有很多数据相同时,可以引入默认值,减少工作量。
13.表中是否可以放入空值:
可以。
14.主键:
用来唯一标识此行的字段,叫主键。
特征:不能重复,不能为空。
1)在建表时添加主键:
Create table stu_4
(
Id int primary key,
Stu_name varchar2(20)
);
Desc stu_4
2)表已经建好,添加主键
Alter table stu_3 add constraint pk_stu_3_stu_id primary key(stu_id);
删除数据:delete stu_4;
15.若有多张表,标间是有联系的,联系是通过外键建立的
外键:有2张表,一张表中有一个字段,他去引用另一张表的主键字段,那么这个字段叫这张表的外键字段。
从表(子项) 主表(父项)
Stu_4 course
S_id (主键) c_id(主键)
S_name c_name
C_id(外键)

Create table course_4
(
C_id int,
C_name varchar2(20)
);

Alter table course_4 add constraint pk_course_4_c_id primary key(c_id);

Alter table stu_4 add c_id int;

Alter table stu_4 add constraint fk_course_4_stu_4_c_id foreign key(c_id) references course_4(c_id);
16.快速新建一张表:
Create table course_5 as select * from course_4 where 1=2;
insert into student2 select * from student;
17.关于表名:
1)必须字母开头
2)字符数目1—30个字符之间
3)包含符号:a-z A-Z 0-9 _ $ #
4)取名建议最好不要与其他对象同名。
5)不要去oracle中的关键字作表名。
18.表放入表空间:
Create table 表名
(字段 )
Tablespace 名称;
三、数据库完整性约束
1. 指的是数据的可靠性和精准性。
目的是防止数据库中存在不符合要求的数据,会由于错误的输入导致无效的输出。

场景: 身份证15-18位;
性别选择;
银行卡卡号:19位
2.数据库完整性分类:
1)实体完整性:要求主键不能重复。
2)域完整性;属性 字段 列完整性,如年龄1-100岁之间
3)引用完整性:外键完整性,引用关系
4)自定义完整性
3.如何保证数据完整性,使用约束
4.常见的约束有:
1)主键约束 primary key
2)外键约束 foreign key
3)唯一约束 unique
4)非空约束 not null
5)默认值约束 default
6)检查约束 check
语法:alter table 表名 add constraint 约束名 约束类型(字段名)
主键约束:alter table stu_3 add constraint pk_stu_3_stu_id primary key(stu_id)
外键约束:alter table stu_3 add constraint fk_stu_3_course foreign key(c_id) references course(c_id);
唯一约束:alter table stu_5 add constraint uq_stu_5_stu_id unique(stu_id);(不约束空值)
非空约束:alter table stu_5 modify stu_id not null;
默认值约束:alter table stu_5 add gender varchar2(2) default‘男’;
检查约束:要求添加学生年龄在18-25之间
alter table stu_5 add age int;
alter table stu_5 add constraint ck_stu_5_stu_age check(age>=18&&age<=25);
现场检查:对学生姓名进行检查,姓名以M开头
alter table student add constraint ck_student_name check(stu_name like ‘m%’);
5.级联删除
alter table stu_3 add constraint fk_stu_3_course foreign key(c_id) references course(c_id) on delete cascade;
删除主表数据,观察从表的数据。
on delete set null;
6.主外键小结;
1)主键和外键都是维护夺标关系的手段,是一种约束。
2)当主表中没有对应的记录时,不能将记录添加到子表。
3)不能更改主表中的值,导致子表的记录发生孤立,而报错。
4)字表存在与主表对应的记录时,不能从主表删除该记录,要使用on delete cascade可以删除。
5)删除主表前,先删除子表。
行:元组 记录
列:属性 字段
7.查看表中哪一个字段做了约束
user_constraints
select * from user_cons_columns where table_name=’emp1’;
8.暂停约束;
alter table stu_4 disable constraint fk_stu_5_course_4_c_id;
9.打开:disable–>enable;
小结:
约束类型:6个
启用
停用
级联删除
四、数据库的设计
范式:
1nf:第一范式,对于表中的每一行中的列,必须具备原子性。
学生表:
姓名 性别 年龄 成绩 所在地区
1 男 11 99 中国北京
2 女 18 88 中国上海
2nf:第二范式,满足1nf,除了主键以外的其他列,都要依赖于该主键。
学生基本表: 编号 姓名 性别 年龄 成绩编号
成绩表: 编号 成绩
3nf:第三范式,满足2nf,除了主键以外的其他列,都不发生传递依赖。
(字段间不能有依赖关系)
学生基本信息表:
编号 姓名 专业 所在系(改为系编号) (专业和所在系有依赖关系)
系表:编号 系名 系地址
1 数学系 2号楼

小结:设计表要根据业务需求设置,即根据3大范式。

画图:
1)E-R图:Entity-Relationship
实体:矩形
属性:椭圆
联系:菱形
分类:1)1对1 1:1
2)1对多 1:n
3)多对多 m:n
学生和课程:
word:
visio:
Sybase公司 pd:
2)物理结构图:
表间联系图
实体:
属性:
联系:

五、查询语句
1.语法:select 字段名 1,2,3.。。。*(通配符)
From 表名/视图名
Where 字段名=值
2.投影查询:
列出表中的某一列或几列,之间用逗号隔开。
举例:列出学生姓名和年龄
Select stu_name as 姓名
from stu_4 学生表;
3.书写sql(结构化查询语言)语句时的规范:
1)写sql时,不区分大小写。
2)写sql时,建议多行。
3)关键词书写时不能换行。
4)可以适当的将语句缩进,提高可读性。
5)关键词一般大写,其他小写。
4.以oracle中自带的用户scott下有一些表:
1)emp:员工表
2)dept :部门表
3)salgrade:工资等级表
4)bonus:分红表
5.基本操作:
1)列出员工的薪水增加500元以后的结果:
select ename 姓名,sal 原始薪水,sal+500 以后薪水
from emp;
where
2) 计算1+1,列出系统当前时间:
Dual表:伪表
select 1+1 结果 from dual;
Select sysdate from dual;
3)查询员工姓名为史密斯的员工的职位信息,员工姓名XXX的职位是XXX
select ‘员工姓名’ ||ename||’的职位’||job from scott.emp
4)查询3天以后的日期:
select sysdate+3 三天以后的时间
from dual;
where
5)查询员工编号不是7369的员工信息
select *
from emp
where empno <> 7369;
6)查询员工工资高于1000
select * from emp where sal>1000;
7)查询员工信息,要求员工编号大于以下列表中的所有编号
select empno,ename,sal
from emp
where empno>all(7369,7521,7654);
8)查询没有福利的员工
select * from emp where comm is null;
select * from emp where comm is not null;
9)员工编号不是数字
select *
from emp
where empno is nan

10)列出员工姓名中有a的员工信息
select * from emp where ename like ‘%a%’;
select * from emp where ename like ‘_a%’;
六、函数
1.分类:
1)单行函数:
1.1)字符函数
concat(x,y):字符串拼接函数,相当于||
举例:列出员工姓名和职位:
Select concat(ename,job) 员工信息
From emp;
Initcap(x);把字符串的首字母变大写。
Upper():转大写
Lower():转小写
Length():字符串的长度
举例:列出员工姓名长度
Select length(ename)
From emp
Where ename=’SMITH’;
Instr(x,fing_string,[start],[occurence]):返回指定字符串find_string在x中的位置
Start:开始位置
Occurence:代表字符出现的次数
举例:找出hello中第二个l出现的位置
select instr(‘hello’,‘l’,2)
from dual;
Lpad()/rpad():字符串左右填充字符的函数
Lpad(x,width,[pad_string]);
举例:hello前面填充*,使其达到13
select lpad(‘hello’,13,’*’)
from dual;
Ltrim()/rtrim()/trim():去除字符串中指定的两边的字符
Ltrim(x,trim_string);
select ltrim(00hello,0)
from dual;
Nvl(x,value):把一个null值转成另外一个值。若x是null,返回value。否则返回x.。
举例:列出员工薪水和福利,只列出有福利的。
select sal,nvl(comm,’无福利’)
from emp;
nvl2(x,value,value2);x不为空返回value,否则返回value2
select sal,nvl(comm,’有’,无)
from emp;
Replace(x,search_string,replace_string):
从字符串x中进行搜索,找出指定字符串,然后使用replace_string进行替换.
select ename,replace(ename,upper(‘smith’),’史密斯’)
from emp;
Soundex(x):返回代表字符串的语音形式
语音相同,拼写不同
举例:找出和to同音的单词。
1.2) 数字函数:
Abs(values):绝对值
Ceil(value):大于等于该数的最小整数
Floor(value):小于等于该数的最大整数
Mod(m,n):返回m和n的余数
Sqrt():取平方根
Trunc(value,n):截断函数
对value进行判断,若N>0,则保留n位小数;
若n=0,则去掉小数部分
若n<0,则保留-n位整数
Round(value,
):四舍五入
对value进行四舍五入,保留
1.3)转换函数
目的:从一种类型转换成另一种类型。
To_char(x,[format]):将x转换成字符串,format是要转换的格式
举例:将数字转成字符串
12345.67
select to_char(12345.67)
from dual;
列出员工信息员工入职的年份:
Select to_date(hiredate,’yyyy’)
From emp;
To_number(x,[format]);
Cast(x as type):将转为指定的兼容的类型
Select cast(12345.36 as varchar2(10)),cast(‘12-5-18’ as date),
Cast(‘23.58’ as nuber(4,2))
From dual;
To_date(x,[format]):日期转换
列出6个月后的日期:
Select to_date(‘sysdate’,to_char(’MM’+6))
1.4)
2)多行函数:
聚合函数:可以提供分组的函数
分类:
(1)max():
(2)Min():
(3)Avg():
(4)Sum():
(5)Count();统计
举例:统计员工表中的平均工资
select deptno,avg(sal) from emp group by deptno;
对每位员工工资增加200后求平均工资
select avg(sal+200) from emp;
求sal的最大值和最小值
select max(sal),min(sal) from emp;
求每个部门的平均工资:
select deptno,avg(sal) from emp group by deptno;
Group by 分组 加字段名。位置写在from后,group by后面的字段,必须是select处出现的字段。
select job,avg(sal)
from emp
group by job
求部门的平均工资超过900的部门编号
select deptno,avg(sal) 平均工资 from emp group by deptno having avg(sal)>900;

having和where 的区别:
where处不允许加入聚合函数,只能在having处
having位置处于group by后面,这个是代表:先分组在筛选。
where在from后面,代表:先筛选再分组。
七、多表查询:
1.为何会有多表查询?
范式:设计数据表
不同的数据存储在不同的表,通常要查询多张表才能找到相应的数据。
2.多表查询语法:
Select 字段名
From 表1,表2
Where 多张表的查询权限
1)列出员工编号7369的姓名,薪水,部门名称等信息
select e.ename,e.sal,d.dname,d.deptno
from emp e,dept d
where e.deptno=d.deptno
and e.deptno=7369;
2)未作两表间联系查询出来的是笛卡儿积,在实际查询中,一定要避免。
3)查询出员工的编号,姓名,工资,部门名称,工资等级,员工工资在最高工资和最低工资之间:

select e.empno,e.ename,e.sal,d.dname,d.deptno,s.grade
from emp e,dept d,salgrade s
where e.deptno=d.deptno
and e.sal between s.losal and s.hisal ;
3.多表查询的连接
连接分类:
等值:
非等值:<> != >= <= like,in,or
4.多表连接查询
连接类型:
1)内连接
inner join…on适用于2张或多张表,必须要返回满足条件的数据,数据不能有空。
select e.,d.
from emp e,dept d
where e.deptno=d.deptno
内链接:
select e.,d.
from emp e inner join dept d
on e.deptno=d.deptno;

2)外连接
Outer join…on 同上,必须返回满足条件的数据,数据可以有null值。
分类:2.1)左外连接 left outer join 左表为主,不会出现null值
2.2) 右外连接:right outer join 右表为主,不会出现null 左有null
2.3) 全外连接:full outer join 合并左右结果
举例:所有员工的所有信息
select e.,d.
from emp e right join dept d
on e.deptno=d.deptno;
3)自连接
举例:列出员工和上级
select e1.ename 员工,e2.ename 上级
from emp e1,emp e2
where e1.mgr=e2.empno;
右外连接:
select e1.ename 员工,e2.ename 上级
from emp e1 right outer join emp e2
on e1.mgr=e2.empno;
换一种方式:

select e1.ename 员工,e2.ename 上级
from emp e1,emp e2
on e1.mgr=e2.empno(+);
“+”是oracle中的一个代表外连接的标志,加号加在哪边,那边就会有空值
右边----左外连接
左边—右外连接
练习:
显示员工姓名的后三个字符:
select substr(ename,-3,3) from emp;
列出员工信息和部门信息:
select e.ename,d.deptno
from emp e inner join dept d
using(deptno);
可以使用user ing关键词,必须是等值连接时使用
显示所有员工信息(显示所有部门)
select *
from emp e,dept d
where e.deptno(+)=d.deptno;
显示所有员工信息(显示所有员工)
where e.deptno=d.deptno(+);
注意:连接适用于显示多表间大量的结果

八、子查询(多表查询的一种)
概念:嵌套查询。
通过子查询,可以使简单的语句组成强大的select语句。
语法:select…(select *…);
1.分类:
1)单行子查询
内部的select语句给外部的select语句返回0行或1行数据。
写在何处:可以加在select、where、having、from
举例:查询员工薪水高于smith薪水的员工
select ename,sal
from emp
where sal>(select sal
from emp
where ename=upper(‘smith’));

select ename,sal
from
(select ename,sal
from emp
where ename=upper(‘smith’)) e;
举例:列出员工和上级的姓名:

select e.ename 员工姓名,(select d.ename from dept d
where e.mgr=d.empno) 上级姓名
from emp e;
举例:列出每个部门的薪水高于平均工资的员工姓名,编号
select e.ename,e.deptno
from emp e
order by e.ename,e.deptno
having sal>(select avg(sal) from emp);
举例:查询任意满足工资低于最低工资的员工信息
select e.*
from emp e
where sal<any(select sal from emp);
2)多行子查询
3)多列子查询:
Select deptno,sal
From emp
Where
In
(
Select deptno,min(sal)
From emp
Group by deptno
);
举例:
select empno,ename
from emp
where (empno,ename) in
(
select deptno,sal
from emp
group by deptno
having sal>avg(sal)
);
4)关联
5)嵌套
2.子查询在update和delete中的应用
举例1:将员工编号为7499的工资更新,改为最高薪水的平均工资。
update emp
set sal

Select avg(hisal) from salgrade

where empno=7499;
举例2:删除表中重复的行。stu;(id,age)
delete
from stu
where id in
(
select id
from stu
group by id
having count(id)>1
);
伪表:select sysdate from dual;
伪列:select rowid id,age from stu;
Rowid:行id,用来唯一标识此行
Rownum:行数
delete
from stu s1
where s1.rowid>
(
select min(rowid)
from stu s2
where s1.id=s2.id);
举例3:要求一张表中的列出其中的前10行数据
select *
from emp e1
where rownum<=10;
如何使用oracle数据库进行数据分页:
select *
from (
select *
from emp e1 --结果集
where rownum<=10
) t
where t.rownum>5;

九、数据库对象
1.序列
概念:序列是数据库对象,用于生成一系列的整数值
语法:create sequence 名字 (简单和复杂创建)
Start with 1 开始
Increment by 1 增量
Maxvalue 1000
Minvalue 1
No cycle 不循环
检查序列:
select seq111.nextval from dual;
select seq111.currval from dual;
查看序列名:select * from user_sequences;
序列的含义:为了给表中的主键填充值
删除序列:drop sequence seq111;
2.索引
概念:一种与表相关联的一种可选结构
创建索引的目的:加快对表执行sql语句的速度
优缺点:
优点:加快检索数据速度
加快表间的连接
在group by和order by 子句中使用索引,可以减少查询中分组和排序所用的时间。
缺点:创建和维护索引都要消耗时间
索引占用物理空间
对数据进行crud,索引也需要动态维护。
索引分类:
1)B Tree(平衡树,普通索引):适用于高基数的列,一般没有特别情况,都要创建普通索引。
2)唯一索引:是B-Tree的一种形式,用于强制列的唯一性。一般与唯一约束一起使用。可以单独创建。
3)位图索引:(bitmap)一般适用于低基数列。使用and,or运算符的环境。
4)函数索引:适用于使用了sql函数的列,一般可以和B-TRee和位图索引结合使用。
5)主键索引:用主键做的索引,不用单独创立。
创建索引:
普通索引:
Create index 索引名
On 表名
Create index ix_stu_s_id on 表名(字段名);
为 stu_11,age字段建立唯一索引
Create unique index ix_stu_11_age on stu_11(age);
查看索引:select * from user_indexes
查询索引所在的列:select * from user_ind_columns;
位图索引:
Create bitmap index ix_bm_age on stu_11(age);
删除:drop index 索引名
创建函数索引:必须要有函数
Create index ix_func_stu_age on stu(min(age)) ;
咋样体现函数索引的价值:
修改alter index 要修改的索引名称 rename to 新的名字

3.视图
概念:是虚表,把复杂的查询用视图来体现,隐藏复杂的业务逻辑。
视图的数据基于真实的表,这张真实的表,叫基表。
用户访问视图中的数据,有权限。
视图创建:(or replace)
Create view 视图名
As
Select
From
查看视图数据
Select * from 视图名;
视图中可以插入数据:insert into 视图名 values();(尽量不用)
基表不存在,视图创建:
Create or replace force view 视图名
As
Select *
From aaa;
视图分类:
1)简单视图:查询语句只涉及一张基表
2)复杂视图:查询语句涉及多张基表
4.同义词
概念:名称不同,但是含义类似的,使用同义词,可以访问相同的对象,方便访问其他用户的对象。
可以缩短要访问的对象名称的长度
分类:
1)公共同义词
2)私有同义词
语法:create synonym 名称 for object;
举例:访问emp表。使用同义词
Create public synonym ee for sysytem.emp;公共
十、oracle开发语言:pl/sql
1.概念:过程语言/结构化查询语言
2.由块组成,一共三块:
1)声明块:declare:用来声明变量、常量,自定义的数据类型
2)主体块
Begin:主体开始
Exception 异常块
End:主体结束
3)异常块:exception
举例:打印hello world
begin
dbms_ouput.put_line(‘hello world’);
end;

–让控制台打开输出
set serveroutput on
声明变量
Declare
s_name varchar2(20);
s_name1 varchar2(20):=’jack’;声明同时赋值
begin
dbms_ouput.put_line(s_name);
end;
举例:列出员工编号为7499的员工姓名,要求使用pl/sql程序输出。
declare
ename emp.ename%type;
begin
select ename
into ename
from emp
where empno=7499;
dbms_output.put_line(ename);
end;
3.Plsql数据类型:可以使用oracle中声明的数据类型
独有类型:
%type:使用某张表中字段的类型作为此变量类型
%rowtype:使用表中的一行做数据类型
列出员工姓名为smith的编号,姓名,薪水字段
declare
emp1 emp%rowtype;
begin
select *
into emp1
from emp
where ename=‘SMITH’;
dbms_output.put_line(‘编号:’||emp1.empno||‘姓名:’||emp1.ename||‘薪水:’||emp1.sal);
end;
Pl/sql支持的有效字符:
包括大小写,0-9,操作符:-+*/=@%
最长可以为30个字符
常量如何赋值:
Declare
PASS_SCORE constant int:=60;
手工输入
手工输入的提示:accept 变量名 prompt ‘显示消息’;
Acept age promt ‘请输入年龄:’;
Declare
D int;
Begin
N:=&age;
Dbms_output.put_line(‘您输入的年龄是:’||n)
End;
异常判断:没有数据异常
declare
emp1 emp%rowtype; --声明模块
begin
select *
into emp1
from emp
where ename=‘smith’;
dbms_output.put_line(‘编号:’||emp1.empno||‘姓名:’||emp1.ename||‘薪水:’||emp1.sal);
exception
when no_data_found then
dbms_output.put_line(‘没有找到需要的数据!’); --异常模块
when others then
dbms_output.put_line(‘其它异常!’);
end;

4.流程控制语句:(判断语句)

  1. if … then … end if;
  2. if … then … else … end if;
  3. if … then …elsif … else … end if;
  4. case 【变量名】 when 条件 then … ; when 条件2 then … else … ;end(case);
    举例1:显示编号为7499的工作进行说明
    Declare
    job emp.job%type
    job_title varchar2(20);
    Begin
    Select job,
    Case
    When job=‘SALESMAN’ then ‘销售员’
    Else ‘以上都不是’
    End
    Into job,job_title
    From emp
    Where empno=7499;
    dbms_output.put_line(job||’’||job_title)
    End;
    举例2:薪水大于800
    Declare
    sal emp.job%type;
    Begin
    Select sal
    Into sal
    From emp
    Where empno=7499;
    if sal>800 then
    dbms_output.put_line(‘正式员工’);
    else
    dbms_output.put_line(‘非正式员工’);
    end if;
    End;

举例3:判断i的值
declare
b int:=1;
begin
b:=(case b
when 1 then 100
else
200
end);
dbms_output.put_line(‘i的值:’||b);
end;
举例3:当员工编号为7499时,输出1,若不是 输出2;
5.循环结构
1)loop 循环条件 end loop;
2)Loop … if … exit end if; end loop;
3)Loop exit when 条件 end loop;
4)While 条件 … loop ,,, end loop;
5)For 循环变量 in 范围 loop … end loop;…
举例1:实现1到4的累加
declare
varNum integer:=1;
varSum integer:=0;
begin
loop
–对和进行累计
varSum:=varSum+varNum;
dbms_output.put(varNum);
–推出
if varNum=4 then
exit;
end if;
dbms_output.put(’+’);
varNum:=varNUm+1;
end loop;
dbms_output.put(’=’);
dbms_output.put_line(varSum);
end;
6.Plsql异常结构:
语法:
Exception
When 异常情况的名称 then
异常处理代码;
When 异常情况的名称 then
异常处理代码;
。。。
When others then --其他异常情况
异常处理代码;
7.异常分类:
1)预定义异常
No_data_found;没有找到数据
Too_many_rows;多行
Zero_divide;被零除
Value_error;值错误异常
2)自定义异常:
(1)先定义自定义异常变量
(2)在主体中引发自定义异常
(3)异常块中处理引发的异常
十一、事务
1.事务:一系列连续的操作,不可分割,要么成功,要么失败。
2.事务特征:A(原子性)C(一致性)I(隔离性)D(持久性)
3.事务经典特征:commit(提交) rollback(回滚)
4.事务处理:事务在操作中可以设置保存点
语法:savepoint 保存点名
5.事务的隔离级别:一个事务同其他事务隔离的地位
在oracle中,支持事务隔离级别:
2种:
1)read committed;(读取已提交事务)
2)Serializable(串行化)
为何有隔离级别:为了避免并发访问问题
1)脏读;(读了未提交的数据)
2)不可重复读;(每次可以读到不相同的数据)
3)幻读;(插入了新行,读取新行数据)
注意:设置数据库的隔离级别:
Set transaction isloation level
十二、存储过程
1.概念:存储在数据库中供所有用户调用的子程序
2.优点:有名字,可以重复。同时还可以提供运行时参数。
3.语法:create or replace procedure 过程名(参数名 参数类型 数据类型,…)
Is/as
Pl/sql程序
4.参数分类:输入参数:in
输出参数:out
举例:建立过程,输出hello
Create or replace procedure pro_1
Is
Begin
Dbms_output.put_line(‘hello’);
End;
运行:
Execute(exec) pro_1;
举例2:显示当前系统时间
create or replace procedure pro_5
as
begin
dbms_output.put_line(‘当前系统时间为:’||to_char(sysdate,‘yyyy-MM-dd HH24:MI:SS’));
end;
举例3:传入学生编号,年龄,插入到表,编写过程。
create or replace procedure pro_6(sid in int,sage in int)
as
begin
insert into stu_22(s_id,s_age) values(sid,sage);
commit;
end;
输入编号,年龄,输出表中数据的数目;
create or replace procedure pro_8(sid in int,sage in int,num out int)
as
declare
ct int:=0;
begin
insert into stu_22 values(sid,sage);
commit;
select count(s_id) into ct from stu_22;
num:=ct;
end;
运行:
declare ct int:=0;
begin
pro_8(6,6,ct);
dbms_output.put_line(ct);
end;
注意:过程小结
1)一般过程没有返回值。
2)若使用了in参数,值可接受,但不能做输出的值。
3)若使用了out参数,可以接受过程执行完后得到的值。可以有多个。
十三、函数
概念:一段功能代码,必须有返回值。
语法:
Create or replace function 函数名(参数名 参数类型 数据类型)
Return 返回值类型
As/is
Pl/sql
举例:输出hello
举例2:插入员工编号,输出员工薪水

create or replace function f_15(id int)
return int
as
emp_sal int:=0;
begin
select sal into emp_sal from emp where empno=id;
return emp_sal;
end;
运行:
begin
dbms_output.put_line(‘员工薪水为:’||f_15(7499));
end;
举例3:插入员工编号,输出薪水,输出表中的行数

create or replace function f_16(emp_no int,rc out int)
return emp.sal%type
as
emp_sal emp.sal%type;
begin
select sal
into emp_sal
from emp
where empno=emp_no;
return emp_sal;
end;

运行:
declare
rc int;
sal emp.sal%type;
begin
sal:=f_16(7499,rc);
dbms_output.put_line(rc);
dbms_output.put_line(sal);
end;
函数和过程的比较:
相同点:带参数,都有输入,输出
不同点:过程不带返回值,函数必须有返回值。
十四、触发器
1.概念:一段plsql程序,与表相关联,每当一个特定的dml语句在指定的表上发出时,数据库就会自动的
2.类型:
1)语句触发器
2)行级触发器
3.语法:
Create or replace trigger 触发器名
Before |after
Delete|insert|update of column
on表名
[for each row]
When(条件)
Pl/sql
4.两个变量
Old:存储表之前的值
new:存储表的新值
这两个变量叫伪纪录变量。
表:
操作 :old :new
Insert 将插入新的数据行
Update 更新该行的值 更新后的值
Delete 删除该行的值
5.举例1:限制写入以j开头的字符串
create or replace trigger tri_emp
before
insert
on emp
for each row
begin
if :new.ename like ‘J%’ then
raise_application_error(-20000,‘不能以J开头!’);
return;
end if;
end;
举例2:有一张表,stu,4行数据,设计触发器,在更新时,显示4个hello
create or replace trigger tri_stu
before
update
on stu
for each row
begin
for i in 1…4 loop
dbms_output.put_line(i||’:’||‘hello’);
end loop;
end;
举例3:限制修改的年龄大于之前的年龄
create or replace trigger tri_stu_age
before
update
on stu_12
for each row
begin
if :new.s_age>:old.s_age then
dbms_output.put_line(‘修改成功!’);
else
raise_application_error(-20000,‘限制大于旧的年龄!’);
return;
end if;
end;
举例4:对stu执行更新,删除,添加操作,显示一个hello.
create or replace trigger tri_stu_12_dml
before
update or insert or delete
on stu_12
for each row
begin
dbms_output.put_line(‘hello’);
end;
举例:
create or replace trigger tri_stu_12_j
before
update or insert or delete
on stu_12
for each row
begin
if inserting then
dbms_output.put_line(‘这是插入!’);
else if deleting then
dbms_output.put_line(‘这是删除!’);
else
dbms_output.put_line(‘这是更新!’);
end if;
end;
举例6:插入学生数据,当插入编号为8的学生信息时,激活触发器
create or replace trigger tri_stu_12_w
before
update or insert or delete
on stu_12
for each row
when(new.s_id=8)
begin
dbms_output.put_line(:new.s_id);
end;
举例7:更新stu表的age字段,激活触发器。要求列出更新前和更新后的值。
create or replace trigger tri_stu_ud
before
update of s_age
on stu_12
for each row
begin

dbms_output.put_line('更新前的值:'||:old.s_age||'   更新后的值:'||:new.s_age);
end;

触发器查询:
触发器名:select * from user_triggers;
源码:select * from user_source;
举例8:触发器中是否可以调用过程
过程:
create or replace procedure pro_1(age1 int)
as
id_1 stu1_11.id%type;
age_1 stu1_11.age%type;
begin
select id,age
into id_1,age_1
from stu1_11
where age=age1;
dbms_output.put_line(id_1||age_1);
end;
触发器:
Create or replace trigger tri_stu10
Before
Insert
On stu1_11
For each row
Begin
Pro1(10);
End;
十五、游标
1.概念:是一个内存工作区,以变量的形式体现,用来临时存储从数据库中提取的数据块,是一个容器。
2.分类:
1)隐式游标
一般针对的是dml语句。关键词:sql
特点:不需生命,直接使用。
属性:
Notfound
Found
Isopen
Rowcount
注意:游标在使用时,必须要打开
使用属性时,sql%notfound
举例1:更新学生表的年龄。若没有记录,则显示没有此记录。
declare
begin
update stu1_11
set age=31
where id=21;
if sql%notfound then
raise_application_error(-20000,‘没有此记录!’);
end if;
end;
举例2:找出编号7369的员工姓名,要求记录已经存在
declare
emp_name emp.ename%type;
begin
select ename
into emp_name
from emp
where empno=7369;
if sql%found then
raise_application_error(-20000,‘存在此记录!员工姓名为:’||emp_name);
end if;
end;
举例3:stu,对此表进行数据的更新,请输出你更新了多少行数据。begin
update stu1_11
set age=111
where id=8;
dbms_output.put_line(‘更新了’||sql%rowcount||‘行’);
–对游标进行判断
if sql%isopen then
dbms_output.put_line(‘打开’);
end if;
end;
2)显示游标

定义语法:cursor cursor_name is select caluse
打开游标语法:open cursor_name;

操作语法:fetch cursor_name into someVar(变量)
退出语法:exit when cursor_name%notfound
关闭语法:close cursor_name
举例:列出员工表中所有员工的编号和姓名
declare
cursor c1 is select empno,ename from emp;
rs emp%rowtype;
begin
open c1;
loop
fetch c1 into rs.empno,rs.ename;
exit when c1%notfound;
dbms_output.put_line(‘行数:’||c1%rowcount||‘编号:’||rs.empno||‘姓名:’||rs.ename);
end loop;
if c1%isopen then
close c1;
end if;
end;
举例2:上例如何显示所有的字段
declare
cursor c1 is select * from emp;
rs emp%rowtype;
begin
open c1;
loop
fetch c1 into rs.empno,rs.ename,rs.job,rs.mgr,rs.hiredate,rs.sal,rs.comm,rs.deptno;
exit when c1%notfound;
dbms_output.put_line(‘行数:’||c1%rowcount||‘编号:’||rs.ename);
end loop;
if c1%isopen then
close c1;
end if;
end;
举例:列出所有员工的编号和姓名,使用for循环。
declare
cursor c2 is select empno,ename from emp;
rs emp%rowtype;
ct int:=0;
begin
open c2;
select count(empno) into ct from emp;
for i in 1…ct loop
fetch c2 into rs.empno,rs.ename;
exit when c2%notfound;
dbms_output.put_line(‘行数:’||c2%rowcount||‘编号:’||rs.ename);
end loop;
if c2%isopen then
close c2;
end if;
end;
综合案列:
要求:按员工的工种涨工资,总裁1000;经理800,其他400,请使用游标实现。
declare
cursor c2 is select sal,empno,job from emp;
rc emp%rowtype;
begin
for rc in c2 loop
if rc.job=‘PRESIDENT’ then
update emp set sal=rc.sal+1000 where empno=rc.empno;
dbms_output.put_line(rc.job||’ '||rc.sal);
end if;
end loop;
if c2%isopen then
close c2;
end if;
end;

3)动态
关键词:ref cursor
与其他游标的区别:
动态游标可以通过在运行期间传递参数获取数据结果集。
显示游标是在编译期间获取数据结果,他们是静态的。
使用步骤:
1)定义一个游标类型,类型为ref cursor
语法:type 数据类型名称 is ref cursor
2)定义游标变量,指明游标变量类型
3)定义动态的sql语句。
4)打开游标 语法:open 游标名 for sql语句
5)操作数据
6)关闭。
举例1:列出员工表所有员工信息。要求员工姓名有字母a。使用动态游标。
declare
–1
type cursor_type is ref cursor;
–2
myCursor cursor_type;
–3
v_sql varchar2(200);
v_emp emp%rowtype;
begin
–4 给V_sql赋值
v_sql:=‘select * from emp where ename like ‘’%A%’’’;
–5打开
open myCursor for v_sql;
–6
loop
fetch myCursor into v_emp;
–6
dbms_output.put_line(v_emp.ename||’ '||v_emp.empno);
exit when myCursor%notfound;
end loop;
–异常
exception
when others then
close myCursor;
–关闭游标
if myCursor%isopen then
close myCursor;
end if;
end;

游标可以带参:
语法:cursor 游标名(参数名,参数数据类型)
举例:从emp中查询员工的姓名和薪水,根据员工的职位。
declare
cursor c1(job1 varchar2) is select ename,sal from emp where job=job1;
ename1 emp.ename%type;
sal1 emp.sal%type;
begin
open c1(‘CLERK’);
loop
fetch c1 into ename1,sal1;
exit when c1%notfound;
dbms_output.put_line(ename1||’ ‘||sal1);
if c1%isopen then
close c1;
end if;
end loop;
end;
举例2:查询员工信息,根据编号。
declare
cursor c1(empno1 varchar2) is select * from emp where empno=empno1;
emp1 emp%rowtype;
begin
open c1(7499);
loop
fetch c1 into emp1;
exit when c1%notfound;
dbms_output.put_line(emp1.empno||’ ‘||emp1.ename||’ ‘||emp1.job||’ ‘||emp1.mgr||’ ‘||emp1.hiredate||’ ‘||emp1.sal||’ ‘||emp1.comm||’ '||emp1.deptno);
if c1%isopen then
close c1;
end if;
end loop;
end;

综合案例:使用游标删除指定的表:删除19年以后创建的表。
declare
cursor cur is select object_name
from user_objects
where object_type=‘TABLE’
and created>to_date(‘2019’,‘yyyy’);
v_sql varchar2(200);
v_name varchar2(20);
begin
open cur;
loop
fetch cur into v_name;
exit when cur%notfound;
v_sql:=‘drop table’||v_name;
dbms_output.put_line(v_sql);
–动态执行sql语句
execute immediate v_sql;
end loop;
exception
when others then
–打印错误行号和消息
dbms_output.put_line(sqlcode||’ '||sqlerrm);
close cur;
if cur%isopen then
close cur;
end if;
end;
补充:oracle包资源的使用:
包有两个部分:
1)包规范:类似于java中的接口
2)包主体:类似于java中的实现类,实现规范中定义的函数或过程。
举例:
1.先定义包规范:create or replace package 包名
2. Is
3. 变量名;
4. 要定义的过程名或函数名;
5.再定义包主体:create or replace package body 包主体名
6. Is
7. 要实现的过程和函数
规范:
create or replace package pk1
is
–定义一个变量
age int:=30;
–定义过程名
procedure pp1(empno1 in emp.empno%type);
–函数
function ff1(empno1 in int)
return varchar2;
end pk1;
主体:
create or replace package body pk1
is
–要实现的过程和函数
procedure pp1(empno1 in emp.empno%type);
as
begin
insert into emp(empno) values (empno1);
commit;
end pp1;
function ff1(empno1 in int)
return varchar2;
is
e_ename emp.ename%type;
begin
select ename
into e_ename
from emp
where empno=empno1;
end ff1;
end pk1;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: