数据库—>数据库实例—>表空间(逻辑单位) —>数据文件(物理单位)
新建一个项目:
MySQL:创建一个数据库,创建相应的表
Oracle和MySQL的差别:
别名中不能有特殊字符
null值不能做四则运算
字符串拼接:
在Oracle中双引号主要用来起别名,单引号是用的值
where 和 having的区别:
where后面不能接聚合函数,可以接单行函数
having是在group by之后执行的,可以接聚合函数
字符函数
日期函数
转换函数
注意 nulls 默认值为first
Eg: select * from emp order by comm desc nulls last;
(+)实际上是如果没有对应的记录就加上空值
select * from emp e1,dept d1 where e1.deptno=d1.deptno(+);
查询包含员工的部门信息 exists
select * from dept where exists(select * from emp where emp.deptno=dept.deptno);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MtYjJkFo-1609849184601)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20201229204240640.png)]
rownum:系统自动生成的一列,用来表示行号
rowid:表示每行数据指向磁盘上的物理地址
from - where - group by - having - select - rownum - order by
Oracle中分页查询只能用子查询,通过rownum
union:去除重复的,并且排序
union all:不去重
创建表空间
create tablespace 表空间名称
datafile '文件的路径(服务器上)'
size 大小
autoextend on 自动扩展
next 每次扩展的大小;
删除表空间
drop tablespace 表空间名称;
创建用户
create user 用户名
identified by 密码
default tablespace 表空间名称
Oracle中的角色:connect、resource、dba
dba拥有最高权限
授权
grant 角色|权限 to 用户
revoke 角色|权限 from 用户
varchar:在Oracle中目前支持,以后不一定
varchar2(长度):可变字符长度
char(长度):固定长度字符
number(总长度,小数长度):数字类型
date:年月日时分秒
timestamp:时间戳,比date类型更精确
create table 表名 as 查询语句;
alter table 表名 add 列名 类型;
alter table 表名 modify 列名 类型;
alter table 表名 drop column 列名;
alter table 表名 rename column 旧名 to 新名;
rename 旧名 to 新名;
alter table 从表名 add foreign key(列名) references 主表名(列名);
强制删除(先删除约束,再删除表)
drop table 表名 cascade constraint;
级联删除(删除主表,从表里的相关内容也会删除)
alter table 从表名 add foreign key(列名) references 主表名(列名) on delete cascade;
保存点 :savepoint 保存点名称
视图:
语法:
可以修改数据:
create [or replace] view 视图名 as 查询语句;
创建只读视图:
create [or replace] view 视图名 as 查询语句 with read only;
create synonym dept for view_test3;
类似于mysql中的auto_increment自增长
语法
create sequence 序列的名称
start with 从几开始
increment by 每次增长多少
maxvalue 最大值 | nomaxvalue
minvalue 最小值 | nominvalue
cycle | nocycle是否循环
cache 缓存的数量 | nocache
select seq_test.nextval from dual;查询序列
语法
create index 索引名称 on 表名(列);
注意:主键约束自带主键索引,唯一约束自带唯一索引
declare
变量名 变量类型;
变量名 变量类型:=初始值
begin
end;
--输出语句
dbms_output.put_line()
vsal emp.sal%type //引用型变量
erow emp%rowtype //记录型变量
if语句
declare
age number:=80;
begin
if age<18 then
dbms_output.put_line('小屁孩');
elsif age>=18 and age<50 then
dbms_output.put_line('年轻人');
else
dbms_output.put_line('老年人');
end if;
end;
declare
i int:=1;
begin
while i<=100 loop
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
declare
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
//1 2 3 4 5...10
declare
begin
for i in reverse 1..10 loop
dbms_output.put_line(i);
end loop;
end;
//10 9 8 7 ...1
declare
i int :=1;
begin
loop
exit when i>10 ;
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
普通游标、系统引用游标
游标是用来操作查询结果集的,相当于JDBC中的ResultSet
语法
cursor 游标名 is 查询结果集;
开发步骤
1、声明游标
2、打开游标 open 游标名
3、从游标中取数据 fetch 游标名 into 变量
游标名%found :找到数据
游标名%notfound :没有找到数据
4、关闭游标 close 游标名
//使用普通游标查询员工姓名和工资(不带参数)
declare
cursor vrows is select * from emp;
vrow emp%rowtype;
begin
open vrows;
loop
fetch vrows into vrow;
exit when vrows%notfound;
dbms_output.put_line('姓名:'||vrow.ename||',工资:'||vrow.sal);
end loop;
close vrows;
end;
//使用普通游标查询员工姓名和工资(带参数)
declare
cursor vrows(dno number) is select * from emp where deptno=dno;
vrow emp%rowtype;
begin
open vrows(&dno);
loop
fetch vrows into vrow;
exit when vrows%notfound;
dbms_output.put_line('姓名:'||vrow.ename||',工资:'||vrow.sal);
end loop;
close vrows;
end;
系统引用游标
1、声明游标:游标名 sys_refcursor
2、打开游标:open 游标名 for 结果集
3、从游标中取数据
4、关闭游标
//使用系统游标查询员工姓名和工资
declare
vrows sys_refcursor;
vrow emp%rowtype;
begin
open vrows for select * from emp;
loop
fetch vrows into vrow;
exit when vrows%notfound;
dbms_output.put_line('姓名:'||vrow.ename||',工资:'||vrow.sal);
end loop;
close vrows;
end;
//使用for循环遍历游标
//不需要打开、关闭游标
declare
cursor vrows is select * from emp;
begin
for vrow in vrows loop
dbms_output.put_line('姓名:'||vrow.ename||',工资:'||vrow.sal);
end loop;
end;
declare
--声明变量
begin
--业务逻辑
exception
--处理异常
when 异常1 then
...
when 异常2 then
...
when others then
... 处理其他异常
end;
zero_divide:除零异常
value_error:类型转换异常
too_many_rows:查询出多行记录,但赋值给rowtype类型的值
no_data_found:没有找到数据
异常名 exception;
raise 异常名
-- 抛出自定义异常
declare
cursor vrows is select * from emp where ename='123456';
vrow emp%rowtype;
verror exception;
begin
open vrows;
fetch vrows into vrow;
if vrows%notfound then
raise verror;
end if;
exception
when verror then
dbms_output.put_line('自定义异常');
when others then
dbms_output.put_line('其他异常');
end;
语法
create [or replace] procedure 存储过程名称(参数名 in|out 参数类型,参数名 in|out 参数类型...) is|as
--声明部分
begin
--业务逻辑
end;
创建存储过程
create or replace procedure pro_addsal(in_ename in emp.ename%type,in_sal in emp.sal%type)
as
cur_sal emp.sal%type;
begin
select sal into cur_sal from emp where ename=in_ename;
dbms_output.put_line('当前工资:'||cur_sal);
update emp set sal=sal+in_sal where ename=in_ename;
dbms_output.put_line('涨薪后的:'||cur_sal+in_sal);
commit;
end;
调用存储过程
方式一
call 存储过程名(参数);
方式二(用的最多)
declare
begin
存储过程名(参数);
end;
语法
create [or replace] function 存储函数名称(参数名 in|out 参数类型,参数名 in|out 参数类型...) return 数据类型
is|as
--声明部分
begin
--业务逻辑
end;
-- 用函数查询指定员工的年薪
create or replace function getsal(in_ename in emp.ename%type) return emp.sal%type
is
vsal emp.sal%type;
begin
select sal*12+nvl(comm,0) into vsal from emp where ename=in_ename;
return vsal;
end;
-- 调用函数
declare
vsal emp.sal%type;
begin
vsal:=GETSAL('SMITH');
dbms_output.put_line(vsal);
end;
-- 查询员工的姓名和年薪
select ename,getsal(ename) from emp;
触发器:当用户执行了insert | update | delete这些操作之后,可以触发一系列其他的动作/业务
作用:
语法
create [or replace] trigger 触发器名称
before | after
insert | update | delete
on 表名
[for each row]
declare
begin
end;
-- 创建触发器
create trigger tig_test1
after insert
on emp
declare
begin
dbms_output.put_line('欢迎加入黑马程序员!');
end;
-- 插入数据
insert into emp (empno,ename)values(9999,'zzl');
触发器的分类
语句级触发器:不管影响多少行,都只会执行一次
行级触发器:影响多少行,就触发多少次
:old 代表旧的记录
:new 代表新的记录
--旧的工资不能大于新的工资
create trigger tri_test1
before
update
on emp
for each row
declare
begin
if :old.sal>:new.sal then
raise_application_error(-20002,'旧的工资不能大于新的工资');
end if;
end;
update emp set sal=sal-10;