2021 Oracle 基本操作一站式学习

Scott(自带表学习适合初学者)

开启scott

解锁scott

alter user scott account unlock --解锁scott用户
alter user scott identified by tiger --解锁scott密码 tiger 可以自定义

登录scott后可以看见4个表

在这里插入图片描述

对表右键 =>View 选择columns可以查看列
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

序列的使用

创建序列

create sequence s_表名 --序列默认从1开始,依次递增,主要给主键赋值

拿取序列下一个值(新创建序列直接拿当前值会报错)

select s_test.nextval from dual

拿取序列当前值

select s_test.currval from dual

单行函数:作用于一行,返回一个值

字符函数

select upper('java') from dual --转换大写
select lower('JAVA') from dual -- 转换小写

数值函数

select round(12.12,1) from dual --四舍五入,第二个参数是保留位数(可以不写,不保留小数点)
select round(52.12,-2) from dual --100 --5四舍五入
select round(52.12,-1) from dual --50 --2四舍五入
select trunc(52.2,-2) from dual-- 与round相似但直接截取不看后面位数
select mod(10,3) from dual --求余

日期函数

--明天此时此刻
select sysdate+1 from dual
--查询入职到至今天数
select sysdate-emp.hiredate from emp
--查询入职到至今几周
select (sysdate-emp.hiredate)/7 from emp
--查询入职距离现在几个月
select months_between(sysdate,emp.hiredate)  from emp
--查询入职距离现在几年
select months_between(sysdate,emp.hiredate)/12  from emp

转换函数

--date转字符串 加fm去除0
select to_char(sysdate,'fm yyyy-mm-dd hh24:mi:ss')  from dual 
-- 字符串转日期
select to_date('2021-1-16 15:32:14','fm yyyy-mm-dd hh24:mi:ss')  from dual

通用函数函数

--nvl 如果是null取第二个参数否则是他本身
select nvl(null,0) from dual

条件表达式

--通用写法 mysql 和oracle 通用
--如果是SMITH 替换成中文
select emp.ename,
       case 
         emp.ename
         when 'SMITH' then '史密斯'
           else 
             emp.ename
             end 
 from emp
 --如果是区间需要这样写 when ..then 可以无限
 select emp.sal , 
        case 
          when emp.sal>3000 then '高薪'
            else
              '低薪'
              end
 from emp
 
 
 ----oracle专用  同上替换中文名一样的效果
 
 select emp.ename ,decode(
        emp.ename,
        'SMITH','史密斯',
        emp.ename
 )
 from emp

多行函数(聚合函数):作用于多行,返回一个值

通用函数

 --查询总数量
 select count(1) from emp
 --查询工资总和
 select sum(sal) from emp
 --查询最高工资
 select max(sal) from emp
 --查询最低工资
 select min(sal) from emp
 --查询工资平均数
 select avg(sal) from emp

分组函数

where 在group by 之前计算 having在group by 之后计算

--查询各部门平均工资
select deptno,avg(sal) from emp 
group by emp.deptno 
--查询平均工资高于2000的部门 先算分组后的平均工资 再筛选平均值大于2000的
select deptno,avg(sal) from emp
group by deptno 
having avg(sal)>2000
--查询员工工资大于800的各部门平均工资  先筛选工资大于200再参与分组
select deptno,avg(sal)  from emp 
where emp.sal>800
group by emp.deptno
--先查出部门员工工资大于800的再查询平均工资大于2000的部门
select deptno,avg(sal) from emp
where sal>800
group by deptno
having avg(sal)>2000

select nvl(null,0) from dual

内连接,外连接

内连接

--算是笛卡尔积内连接
select * from emp,dept
where emp.deptno = dept.deptno
--left join 
select * from dept
inner join emp on dept.deptno = emp.deptno

外连接

--left join 左边是主表  right join右边是主表
select * from dept
left join emp on emp.deptno= dept.deptno 

--oracle 专用外连接 (+)加右边是左连接   (+)加左边是又连接
select * from dept,emp
where dept.deptno = emp.deptno(+)

自连接

--自连接  查询员工姓名,部门名称,领导姓名,领导部门
select e.ename,d.dname,e2.ename,d2.dname from emp e,emp e2 ,dept d,dept d2
where e.mgr = e2.empno
and e.deptno = d.deptno
and d2.deptno = e2.deptno
order by e.ename asc

子查询

--子查询查找工资最低人的姓名,工资,部门,部门编号
select d.deptno,d.dname,e.ename,e.sal from
(select deptno,min(sal)sal from emp group by deptno) ds,emp e,dept d
where ds.sal = e.sal and ds.deptno = d. deptno

分页查询

rownum:每次查询时前面的行号,做分页查询必不可少 (根据查询条数递增从1开始)
例如:我查询前三名 只需要rownum>4
在这里插入图片描述
此时我们只需要再套一层 select * from 那我们又可以拿到一组顺序正常的行号
在这里插入图片描述

注意:rownum 不能大于一个正数 即 rownum>5 因rownum是从1开始依次递增
在这里插入图片描述
以上作为理解!实际rownum不是0开始
最终获取前三行数据

select rownum,e.* from 
(select * from emp order by sal desc) e
where rownum <4 

正式分页 :查询第二页,每页三条

公式带入
例如:pageno (页数)= 1 pagesize(每页大小) 自行带入理解

(pageno-1)pagesize 开始行
pageno
pagesize+1 结束行

select * from (
select rownum rn,e.* from 
(select * from emp order by sal desc) e
where rownum <7 
)where rn >3

视图

试图就是提供一个查询的窗口,所有数据来自于原表
注意:创建视图必须有dba权限
准备工作

查询语句创建表

--从 scott用户创建表
create table emp as select * from scott.emp

创建视图

create view v_emp  as select * from emp --with read only  后面加则创建只读视图

对视图进行增删改查

--查询视图
select * from v_emp
--修改视图【不推荐】
update v_emp set job ='xxx' where empno = 7369;
commit;
--和普通增删改一样其他省略

那视图有什么用呢?

  1. 可以选择性的屏蔽一些字段根据查询语句来创建视图
  2. 同是保证总部和分部数据统一(视图改变也会改变原表,反之也一样)

索引

可以增加查询速度,但会影响增删改
单列索引
关键字:index

创建单例索引 (单行函数和模糊搜索都会影响索引)
create index 索引名 on 表名(列名)

复合索引

创建复合索引(or不会触发索引)
create index 索引名 on 表名(列名1,列名2)

create index emp_id_name on emp(id,name)
select * from emp where id ='1' and name ='xx' --触发复合索引
select * from emp where id ='1' or name ='xx'	--不触发索引
select * from emp where id ='1' 	--触发单例索引

PL/SQL编程

定义变量

declare 
  i number(2) :=1; --定义数值变量i  := 赋值  2是长度 
  str varchar2(10) := 'zzz'; --定义字符变量
  ena emp.ename%type; --引用emp表中ename的类型 引用型变量
  emprow emp%rowtype;--记录型变量 存一行数据 类似对象
begin --类似java的左括号 {
  dbms_output.put_line(i); --输出语句
  dbms_output.put_line(str);
  select ename into ena from emp where ename = '张三'; --查询语句给ena 赋值
end; --类似java的右括号 }

if 判断

declare
  i number(2) := &i;  --&i 输入一个值
begin
  if i<18 then  --if 
    Dbms_Output.put_line('小年轻');
  elsif i<40 then  --坑点: java中else if  此处elsif  是els不是else
    dbms_output.put_line('壮士');
  else
    dbms_output.put_line('老了老了');
  end if;--结束if
end;

三种 loop 循环

while循环

declare
  i number(2) := 1;
begin
  while i < 11 loop  --while循环条件
    dbms_output.put_line(i);
    i := i+1; --相当于 i++
    end loop;
end;

exit循环

declare
  i number(2) :=1;
begin
  loop
    exit when i>10;  --满足跳出循环
    dbms_output.put_line(i);
    i := i+1; --i++
    end loop;  
end;

for循环

declare
  i number(2) :=1;
begin
  for i in 1..10 loop --条件   好难用啊
  dbms_output.put_line(i);
  end loop;
end;

游标

可以存放多个对象,多行记录
语法:cursor 游标名称 is 查询语句

declare
  cursor c1 is select * from 表名; --给游标赋值
  motyperow 表名%rowtype;--定义类型
begin
  open c1;--打开游标
  loop
    fetch c1 into motyperow;--遍历游标赋值给 into后面的属性
    exit when c1%notfound; -- 游标为空退出
    dbms_output.put_line(motyperow.seg);--也可以在此处写增删改
  end loop;
  close c1;
end;

存储过程

存储过程:把一段写好的PL/SQL放到数据库中,后续直接调用
语法:

--or replace 可以替换已经存在的 []要去掉里面表示可写可不写
--在视图(VIEW)中只能用AS不能用IS;
--在游标(CURSOR)中只能用IS不能用AS。
create [or replace] PROCEDURE 过程名 [(参数名 in/out 数据类型)] --不写默认in
  AS/is --as 或者 is
  begin
  	plsql子程序体
  end;

注意: 参数类型不能加长度!!!
创建存储过程并使用

create or replace PROCEDURE pagetest (fab xxx.plant%type) --不写默认in
  is 
  begin
    dbms_output.put_line(fab);
  end;

declare

begin
  pagetest('A栋');--使用
end;

out参数的使用

create or replace PROCEDURE  pageOutTest (str varchar2,strappend out varchar2)
is
begin
  strappend := str || '存储过程加BUFF';
end;

--使用
declare
strappend varchar2(50);
begin
  pageOutTest('test',strappend);--执行完会把out出来的值 赋值给我上面定义的strappend
  dbms_output.put_line(strappend);
end;

存储函数

语法:

create or replace function 函数名(name in type,name in type...) return 数据类型 is 结果变量 数据类型;
begin
	return (结果变量);
end 函数名;

创建并使用

create or replace function pageFunctionTest(str varchar2) return varchar2
is strappend varchar2(50);
begin
  strappend := str || '给你加个BUFF';
  return strappend;
end;

--使用
declare
strappend varchar2(50);
begin
  strappend := pageFunctionTest('A栋');
  dbms_output.put_line(strappend);
end;

注意:返回值必须定义一个变量接收
总结:
不难看出存储过程和存储函数好像没有什么区别都可以实现上面的功能,但是存储函数是有返回值的,那么我们就可以自定义函数了,例如:nvl(param1,param2),sum(param)等。
存储过程本质是没有返回值的所以无法自定义函数

触发器

触发器:触发器就是定制一个规则,再增删改的时候,满足规则自动触发
触发器又分两种:

  1. 语句级触发器: 不包含 for each row 的就是语句级触发器
  2. 行级触发器 包含 for each row 的就是行级触发器
    加 for each row 是为了使用 :lod 和 :new 对象(一行记录)

通过触发器自增id

create or replace trigger insertpagezhutest
 before --after之后触发  before之前触发
 insert --插入
 on pagezhutest --表名
 for each row --行级触发器
declare
 autoid int;
begin
  select s_motype.nextval into :new.id from dual;--把序列作为主键
  select s_motype.currval into autoid from dual;
 dbms_output.put_line('新增的id是'|| autoid);

end insertpagezhutest;

完结撒花!
在这里插入图片描述

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值