select * from tab;
sql 分类 ddl 数据定义语言
dml 数据操作语音
dcl 数据控制语言 安全 授权 grant revoke
dql 数据查询语言 select from 字句 where 字句
select {列名 }from 表名 where 条件 groupby 分组条件 having过滤 orderby 排序
select * from tcp;
select 1+1; 在mysql中为2 orcle中报错
select 1+1 from dual; oracle中的虚表 主要用来补齐语法结构的
select * from dual;
/
别名查询 使用as关键字 可以省略
有特殊字符或关键字 用""
/
select eanme "xing ming",sal gongzi from emp;
select distinct job from emp; 单列去除重复的
select distinct job,deptno from emp; 多列去除重复 每一列都一样才算重复
查询中的四则运算
select 1+1 from dual;
查询员工年薪
select sal * 12 from emp;
查询员工年薪+奖金
注意 null值 代表不确定的 不可预知的内容 不可以做四则运算
nvl 函数 如果参数1为null 就返回参数2
select sal12 + nvl(comm,0) from emp;
字符串拼接
java : + 号拼接
oracle : || 拼接 oracle特有的连接符
查询员工姓名 姓名 scott
select ename from emp;
在oracle “”注要是别名的使用 ‘’使用的是值 是字符
select '姓名:'||ename from emp;
concat(str1,str2)函数 MySQL oracle 都有 拼接
select concat('姓名:',ename) from emp;
条件查询 where后面的写法 比较运算符 关系运算符>< = <= != <>
逻辑运算服 and or not
其他运算服 like 模糊查询 int(set)在某个集合内
between and 在某个区间内
is null 判断为null is not null 判断不为null
查询每月能得到奖金的员工信息
select * from emp where comm is not null;
查询工资在1500-3000之间的员工信息
select * from emp where sal between 1400 and 3000
select * from emp where sal > 1500 and sal <=3000
查询名字在某个范围内的员工('jones','scoott','ford')
select * from emp where ename in ('jones','scoott');
模糊查询 like %匹配多个字符 — 匹配单个字符
查询员工姓名第三个字符是o的员工
select *from emp where ename like '__o%'
查询员工姓名中,包含% 的员工信息 如果有特殊字符,可以使用escape
select * from emp where ename like '%%%' escape '';
排序:order by 升序 asc 降序 desc
查询员工信息 按照奖金由搞到低的排序 排序注意null问题 nulls first | last
同时排序多列的话,用,分开
select * from emp order by comm desc nulls last;
查询工资,和部门编号 按照部门升序排序 工资降序 排序
select deptno,sal from emp order by deptno asc,sal desc;
函数:必须要有返回值 单行函数 和多行函数 对某一列的所有行进行处理 1.直接忽略空值
max() min count sum avg
统计员工工资总和
select sum(sal) from emp;
统计员工奖金总和
select sum(comm) from emp;
统计员工个数 14
select count(1) from emp;
统计员工的平均奖金 会有null值干扰
函数 ceil 单行函数 对某一行中的某个值进行处理
数值函数 字符函数 日期函数 通用函数 转换函数
select sum(comm)/count(1)from emp;//存在奖金为null值隐患
select ceil(sum(comm)/count(1))from emp;
数值函数
select ceil(45.926) from dual; 46
select floor(45.926) from dual; 45
四舍五入
select round(45.926,2) from dual; 45.93
select round(45.926,1) from dual;46
select round(45.926,-1)from dual;50
select round(44.926,-1)from dual;40
select round(45.926,-2)from dual;0
select round(55.926,-2)from dual;100
截断
select trunc(45.926,2) from dual; 45.93
select trunc(45.926,1) from dual;45.9
select trunc(45.926,-1)from dual;45
select trunc(44.926,-1)from dual;40
select trunc(45.926,-2)from dual;0
select trunc(55.926,-2)from dual;0
求余
select mod(9,3)from dual; 0
select mod(9,4) from dual;1
字符函数 substr(str1,起始索引,长度)
注意 起始索引不管写0 还是1都是从第一个开始
select substr('abcdefg',0,3) from dual;abc
select substr('abcdefg',1,3) from dual;abc
select substr('abcdefg',2,3) from dual;bcd
获取字符串的长度
select length('abcdefg')from dual;7
去除字符串左右两边的空格
select trim(' hello ')from dual;
select ceil(-12.5) from dual;-12
select floor(-12.5) from dual;-13
select floor(12.5) from dual;12
替换字符串
select replace('hello','1','a')from dual;
日期函数
查询今天的日期
select sysdate from dual;
查询3个月后的今天的日期
select add_months(sysdate,3)from dual;
查询3天后的日期
select sysdate +3 from dual;
多表查询
内连接
等值连接
inner join
外连接
left outer join
right outer join
oracle 特有的写法(+)
内连接的连接
select * from emp e1 emp t1 where e1.mgr=t1.empno;
t1表里面的所有记录都会显示出来,如果t1.empno 在e1.mgr中没有对应的记录,就加null值
select * from emp e1 emp t1 where e1.mgr(+)=t1.empno;
查询不是领导的员工编号
select empno from emp where empno not in(select mgr from emp where mgr is not null)
获取员工的名字和部门的名字
select e.ename,d.ename from emp e,dept d where e.deptno=d.deptno;
使用子查询的方式来完成
select ename,deptno from emp;
select ename,deptno,deptno from emp;
关联子查询,子查询依赖外部查询的条件
select ename,deptno,(select dname from dept d where d.deptno=e.deptno) aa from emp e;
select * from emp;
select * from dept;
第三天
创建表空间
oracle体系结构
数据库 数据库实例 表空间 用户里面创建表 --数据文件
地球 中国 省份(人民) 土地山川河流
雄安新区 人(炒房地产)
创建表空间 逻辑单位,通常我们新建一个项目,就会去新建表空间,在表空间中创建新的用户
语法
create tablespace 表空间的名称
datafile '文件的路径(服务器上)'
size 大小
autoextend on 自动扩展
next 每次扩展的大小
切换到system账号下创建
创建一个表空间 汉东
create tablespace handong
datafile 'c:\handong.dbf'
size 100m
autoextend on
next 10m
删除表空间
drop tablespace handong;
创建用户
create user 用户名
identified by 密码
default tablespace 表空间的名称
create user dakang
identified by dakang default tablespace hangdong;
授权
grant 角色 | 权限 to 用户
grant connect to dakang
授予 dba的角色
grant dba to dakang;
select * from scott.emp;
列的类型
varchar,在oracle中 目前是支持的,但是不保证以后还支持
varchar2(长度)可变字符长度 varchar2(10) hello 占5个字符
char(长度) 固定长度 char(10) hello 占10个字符,用空格填充
number(总长度,小数长度) 数字类型 小数长度不能大于等于总长度
date 年月日 时分秒
timestamp 时间戳 比date类型更加精确
create table test1(
name1 varchar2(10);
name2 char(10);
age number(2,3)
);
insert into test1(name1,name2)values('hello','hello');
select * from test1;
select * from test1 where name1 like 'hello';可以查询出数据
select * from test1 where name2 like 'hello';查不出数据
insert into test1(age)values(2.3);
select current_date from dual;
select current_timestamp from dual;
long/clog :存放一本小说
blog: 存放电影 java 存进去 再读取出来
使用子查询的方式创建表
create table 表名 as 查询语句;复制表
注意:只会复制表结构个表中的数据,不会复制列的约束
如果查询语句有结果,就是复制 表结构和数据
如果查询语句没有结构就是复制表结构
select * from scott.emp;
create table emp as select * from scott.emp;
如果查询语句是没有任何的结果的
select * from scott.emp where 1=2;
select * from emp1 as select * from scott.emp where 1=2;;
修改表
添加列 修改列 varchar2(10)
删除列
修改列名
重命名表
sql分类:
ddl:数据定义语言:修改的结构 alert create drop truncate
dml:数据操作语言:操作表中数据 insert update delete
dcl:是数据控制语言 grant
dq
create table stu(
stuid number,
sname varchar(10)
);
comand window 用sql指令查询
添加一列l:
alter table stu add phones varchar2(11)
alter table stu add(
mobile varchar2(11),
sex varchar2(2)
);
修改列的类型
alter table stu modify sex varchaer2(4);
修改列名 sex -- gender
alter table stu rename column sex to gender;
删除列
alter table stu drop column gender;
修改表名
rename stu to student;
删除表
drop table student;
表的五大约束
列的约束:约束主要是用来约束表中数据的规则
主键约束:primary key 不能为空,必须唯一
非空约束
唯一约束
检查约束 check(条件) 在mysql中是可以写的,但是在mysal直接忽略了检查约束
外建约束 主要是用来约束从表a中的记录,必须是存在b中
男,女,人妖
create table student(
student number primary key;
sname varchar2(10) unique;
age varchar2(10) not null;
gender varchaer2(4) check(gender in('男'),'女','人妖')
);
唯一约束违反
insert into student values(1,'张三','31','男');
insert into student values(1,'张三','31','男');
select * from stu;
非空约束
insert into student values(1,'张三',null,'男');
检查约束
insert into student values(1,'张三','31','妖');
商品分类表和商品表
商品分类表
create table category(
cid number primary key;
cname varchar2(20);
);
创建一个商品表
create table product(
pid number primary key,
pname varchar2(20),
cno number
);
insert into category values(1,'手机数码');
insert into product values(10,'锤子',11); 插入失败
select * from category;
select * from product;
添加外建约束
alter table product add foreign key(con) references
category (cid);
首先主表中必须存在11号,先往主表中插入数据,再往从表中插入数据
insert into category values(2,'电脑办公');
insert into product values(11,'外星人','2')
删除dategory
drop table category; 表中记录被外建关联无非删除
强制删除表(不建议使用):先删除外建关联表的外建约束,然后再删除自己 先删除product 的外建约束,再删除category
drop table category cascade constraint;
drop table product;
级联删除
添加外建约束,使用级联约束,在删除的时候使用级联删除
alter table product add foreign key(con) references category(cid) on delete cascade;
级联删除: 首先去从表中找有没有关联数据 ,如果在从表中找到关联数据,先删除从表中关联数据,
然后在删除主表中的数据
delete from category where cid=2;
truncate table product;
插入数据:
insert into 表名 values(所有列的值都要对应写上)
insert into 表名(列1,列2)values(值1,值2)
使用子查询插入数据
insert into 表名 查询语句
select * from emp1;
select * from emp;
将emp中10号部门的员工信息,插入到emp1中
insert into emp1 select * from emp where deptno=10;
更新数据
update 表名 set列名=列的值(where 条件)
update emp1 set ename='HUAAN' where ename='king'
select * from emp1;
删除数据
delete from 表名 where 条件
delete from emp1 where empno=7839;
delete 和truncate 区别
delete dml 逐条删除 truncate 先删除表再创建表 ddl
dml 支持事务操作 不支持事务操作
执行效率要高
事务:就是一系列的操作,要么都成功,要么都失败
四大特性:原子性,隔离性,持久行,一致性
如果不考虑隔离级别,脏读,虚度,不可重复读
mysql中隔离级别
read uncomitten ,read commited,repeateble read ,serialliazable
oracle 中隔离级别: read committed serializable read only
默认隔离级别:read committed
提交:commit
事务的保存点/回滚点:savepoint 保存点的名称
回滚: rollback
create table louti(
lou number primary key
);
insert into louti values(1);
insert into louti values(2);
savepoint dangban;
insert into louti values(3);
insert into louti values(4);
rollback to dangban
submit;
declare
begin
insert into louti values(3);
insert into louti values(4);
savepoint dangban;
insert into louti values(5);
insert into louti values(6);
commit;
exception 捕获异常
when other then
rollback to dangban;
end;
select * from louti;
视图:是对查询结果的一个封装
视图里面所有的数据,都是来自了它查询的那张表,视图
本身不存储任何数据
1.能够封装复制的查询结果
2.屏蔽表中的细节
语法
create(or replace) view 视图的名称 as 查询语句
[with read only]
创建一个视图
create or replace view view_test1 as select ename,job,mgr
from emp;
通过视图修改数据
update view_test1 set ename='smith2' where ename='smith'
select * from view_test1;
注意:通常不要通过视图去修改,视图创建的时候,通常要加上with read only
创建一个只读视图
create or replace view view_test1 as select ename,job,mgr from emp with read only;
视图封装复杂的查询语句
create view view test3 as ()
同义词的概念
create synonym dept for view_Test3;
create synonym yuangong for view_Test2;
select * from emp;
select * from dept;
序列的概念·生成类似于auto_increment 这种id自动增长
1,2,3,4,5
auto_increment 这个是mysql
语法:create sequence 序列的名称
start with 从几开始
increment by 每次增长多少
maxvalue 最大值|nomaxvalue
minvalue 最小值|nominvalue
cycle|nocycle 是否循环 1,2,3,1,2,3
cache 缓存的数量3 |nocache 1.2.3.4.5.6
创建一个1,3,5,7.。,30
create sequence seq_test1
start with 1 increment by 2
maxvalue 30
minvalue 0
cycle cache 10;
如何从序列中获取值
currval 当前值
nextval 下一个值
注意 currval 需要在调用nextval 之后才能使用
序列用的最多的一种写法
create sequence seq_test2;
select seq_test2.nextval from dual;
select seq_test.nextval from dual;
select seq_test1.curral from dual;
索引:相当于一本书的目录,提高查询效率
如果某一列,你经常用来作为查询条件,那么就有必要创建
索引,数据量比较大的情况
语法:
create index 索引的名称 on 表名(列)
注意:主键约束自带主键索引,唯一约束自带唯一索引
五百万数据测试
create table wubaiwan(
name varchar2(30),
address varchar2(20)
);
insert into wubaiwan values('')
插入500万条数据
declare
begin
for 1 in 1..5000000 loop
insert into wubaiwan values('姓名'||i,'地址'||i);
end loop;
end
在没有添加索引的情况下,去查询 name='姓名3000000'
select * from wubaiwan where name='姓名3000000';2.95秒
创建索引name 再去查询name='姓名3000000'
create index ind_wubaiwan on wubaiwan(name);
select * from wubaiwan where name='姓名3000000';0.016秒
在没有添加复合索引的情况下,再去查询name='姓名3000000'and'地址3000000'
select * from wubaiwan where name='姓名3000000'and address='地址3000000'; 0.032秒
创建复合索引的情况下,再去查询
create index inde_wubaiwan2 on wubaiwan (name,address);
select * from wubaiwan where name='姓名3000000'and address='地址3000000';0.015秒 f5
sql:优化 建立索引
1.cost cpu调用次数
2.cardinality影响行数
索引原理:
btree balance Tree 平衡二叉树
如果某列作为查询条件的时候,可以提高查询效率,但是修改的时候,会变慢
索引创建好之后,过了一段时间,dba都会去做重构索引
sql调优:
查看执行计划 f5
1.cost cpu调用次数
2.cardinality影响次数
ddl表空间操作
创建表空间
创建用户
授权
创建表
子查询创建表
修改表:添加列,删除列,修改列,修改列名,修改表名
约束
主键约束,唯一约束,非空约束,检查约束,外建约束
外建约束; 强制删除 级联删除
dml表中数据
插入数据
子查询插入数据
更新数据
删除数据:delete 和truncate
事务操作:
savepoint 保存点
rollback to 保存点
oracle事务隔离级别:默认是read comitted
视图:就像窗户一样:封装查询结果,通常视图创建只读视图
序列:主要是用来实现id自增长的 不回头
索引:相当于是书的目录,能够提高查询效率 原理:平衡二叉树,每隔一段时间dba都需要去重建索引
同义词:create synonym 名称 for 对象的名称
1.列出至少有三个员工的所有部门和部门信息
1.分组统计每个部门的员工数量
select deptno ,count(1) from emp group by deptno;
找出员工数量至少3
select deptno ,count(1) from emp group by deptno having count(1)>=3;
查询出部门信息
select * from ( select deptno ,count(1) from emp group by deptno having count(1)>=3) t1,detp d1
where t1.deptno=d1.deptno;
2.列出受雇日期早于直属上级的所有员工的编号,姓名,部门名称(dept)
---查询员工的编号,姓名,员工的受雇日期,经理的编号,经理的受雇日期
select e1.empno,e1.ename,e1.hiredate,m1.empno,m1.hiredate
from emp e1,emp m1
where e1.mgr=m1.empno;
早于
select e1.empno,e1.ename,e1.hiredate,m1.empno,m1.hiredate
from emp e1,emp m1
where e1.mgr=m1.empno and e1.hiredate<m1.hiredate;
查询员工的部门名称
select e1.empno,e1.ename,e1.hiredate,m1.empno,m1.hiredate,d1.dname
from emp e1,emp m1,dept d1
where e1.mgr=m1.empno and e1.hiredate<m1.hiredate and e1.deptno=d1.deptno;
统计薪资 大于 薪资最高的员工 所在部门 的平均工资 和 薪资最低的员工所在部门的 平均工资的 平均工资的员工信息
1.薪资最高
select max(sal) from emp;
薪资最高的员工的部门编号
select deptno from emp where sal=( select max(sal) from emp);
部门的平均工资
select avg(sal) from emp where deptno=(select deptno from emp where sal=( select max(sal) from emp));
薪资最低800
select min(sal) from emp;
薪资最低的员工所在的部门 20
select deptno from where sal=(select min(sal) from emp);
部门的平均工资
select avg(sal)from emp where sal=( select deptno from where sal=(select min(sal) from emp));
查询上面两个部门的平均工资 2545.5
select (2916+2175)/2 from dual;
select (
(select avg(sal) from emp where deptno=(select deptno from emp where sal=( select max(sal) from emp))
+( select avg(sal)from emp where sal=( select deptno from where sal=(select min(sal) from emp));))/2
)
工资大于 上面两个部门的平均工资
select * from emp where sal>();
PlSQL编程:p'roceduce language 过程语言 oracle对sql的一个扩展
让我们能够像在java中一样写 if else else if 条件 还可以编写循环逻辑 for while
declare 声明变量
变量名 变量类型;
变量名 变量类型 :=初始值;
vsal emp.sal%type; --引用型的变量
vrow emp %rowtype; --声明记录型变量
begin
--业务逻辑
end;
dbms_output.put_line()相当于java中sysc
declare
i varchar2(10) :='张三';
begin
dbms_output.put_line(i);
end;
查询7369的工资,并且打印出来
declare
i varchar2(10) :='张三';
begin
dbms_output.put_line(i);
end;
查询7369的工资,并且打印出来
declare
vsal emp.sal%type;
begin
将查询出的结果复制给vsal
select sal into vsal from emp where empno=7369;
dbms_output_line(vsal);
end;
查询7369的员工信息,并且打印出来
select * from emp where empno =7369;
declare
vrow emp %rowtype;
begin
select * into vrow from emp where empno =7369;
dbms_output_line('姓名:'||vrow.ename || '工资'||vrow.sal)
end;
pl条件判断
if then
elseif then
else
end if;
根据不同年纪,输出相关内容
declare
age number :=&aaa;
begin
if age <18 then dbms_output.put_line('小屁孩')
elseif age>=18 and age <=24 then
dbms_output.put_line('年轻人')
elseif age>24 and age <40 then
dbms_output.put_line('老司机')
else
dbms_output.put_line('老年人')
end if;
end;
循环操作
while 循环
while 条件 loop
end loop;
for 循环
for 变量 in reverse 起始值 .. 结束值 loop
end loop;
loop循环
输出 1-10
declate
i number :=1;
begin
where 1<=10 loop
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
输出 1-1o
declare
begin
for i in 1..10 loop
dbms_output.put_line(i)
end loop;
end;
loop循环
--输出 1-1o
loop
exit when 条件
end loop;
输出1-10
declare
i number :=1;
begin
loop
exit whenn i>10;
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
*
***
使用plsql输出菱形
declare
m number :=2;
begin
for x in -m..m loop
for y in -m..m loop
if abs(y)+abs(x)<=m then
dbms_output.put('*')
else
dbms_output.put(' ');
end if;
end loop;
dbms_output.new_line();
end loop;
end;
序列 oracle使用来模拟id自动增长的
create sequence seq_test4;
create table test2(
tid number primary key,
tname varchar2(10)
);
insert into test2 values(seq_test4.nextval,'张三');
select * from test2;
plsql编程:过程语言,编写一些复杂的业务逻辑
输出*号
sal emp.sal%type ---引用型变量
row emp%rowtype ---记录型变量
select sal into vsal from emp where empno=7788;
abs(y)+abs(x)<=m
declare
m number :=3;
begiin
for y in -m .. m loop
for x in -m .. m loop
if abs(y)+abs(x)<=m then
dbms_output.put_line('*');
else
dbms_output.put_line(' ');
end if;
end loop;
dbms_output.new_line();
end loop;
end;
游标:是用来操作查询结果集,相当于jdbc中resultSet
select * from emp;
语法:curscr 游标名(参数名 参数类型) is 查询结果集
开发步骤:
1.声明游标
2.打开游标 open 游标名
3.从游标中取数据 fetch 游标名 into 变量
游标名%found :找到数据
游标名%notfound: 没有找到游标
4.关闭游标 close游标名
输出员工表中所有的员工姓名和工资(不带参数游标)
结果集 :所有员工
声明一个变量,用来记录一行数据 %rowtype
declare
cursor vrows is select * from emp;
--声明变量,记录一行数据
vrow emp%rowtype;
begin
--1.打开游标
open vrows;
--2.从游标中提取数据
--循环取数据
loop
fetch vrows into vrow;
exit when vrows%not found;
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
1.打开游标,指定10号部门
open vrows(10);
循环遍历,取数值
loop
fetch vrows into vrow;
exit when vrows%notfound;
dbms_output.put_line('姓名:'||vrow.ename || '工资: ' || vrow.sal)
end loop;
close vrow;
end;
系统引用游标
1.声明游标:游标名 sys_reference
2.打开游标:open 游标名 for 结果集
3.游标中取数据
4.关闭游标
输出员工表中所有员工姓名和工资
declare
声明系统引用游标
vrows sys_reference;
声明一个变量
vrow emp%rowtype;
begin
打开游标
open vrow for select * from emp;
取数据
loop
fetch vrows into vrow;
exit when vrow%notfound;
dbms_output.put_line('姓名:'||vrow.ename || '工资:'||vrow.sal)
end loop;
end;
扩展内容————使用for循环遍历游标
declare
声明一个游标
curscr vrows is select * from emp;
begin
for vrow in vrows loop
dbms_output.put_line('姓名:'||vrow.ename || '工资:'||vrow.sal)
end loop;
end ;
for 循环遍历游标:
不需要声明额外游标
按照员工工作给所有员工涨工资,总裁涨1000,经理800 其他人400
游标:所有员工
声明一个记录一行数据
declare
声明一个游标
cursor vrows is select * from emp
声明一个变量
vrow emp%rowtype;
begin
打开游标
open vrows;
循环取数据
loop
退出的条件
exit when vrows%notfound;
根据不同的职位,涨工资总裁涨1000,经理800 其他人400
if vrow.job='presidret' then
update emp set sal =sal+1000 where empno=vrow.empno;
elseif vrow.job='manager' then
update emp set sal =sal+800 where empno=vrow.empno
else
update emp set sal =sal+400 where empno=vrow.empno
end if;
end loop;
根据不同的职位,涨工资
关闭游标
close vrows;
提交事务
commit;
end;
例外:(意外)程序运行的过程中发生异常,相当于java中的异常
declare
--声明变量
begin
--业务逻辑
exception
--处理异常
when 异常:then
when 异常2 then
... 处理其他异常
end;
zero_divide:处零异常
value_error:类型转换异常
too_many_row:查询出多行记录,但是赋值给了rowtype记录一行数据变量
no_date_found:没有找到数据
declare
vi number;
vrow emp%rowtype;
begin
vi:=8/0;
vi:='aaa';
select * into vrow from emp where empno=1234567;
exception
when zero_divide then
dbms_output.put_line('发生了处理异常');
when value_error then
dbms_output.put_line('发生了类型转换异常');
when too_many_rows then
dbms_output.put_line('查询出多行记录,但是赋值给了rowtype记录一行数据变量');
when no_data_found then
dbms_output.put_line('没有找到数据异常');
when others then
dbms_output.put_line('发生了其他异常'|| sqlerrm);
end;
自定义异常:
异常名 exception:
raise 异常名
查询指定编号的员工,如果没有找到,则抛出自定义的异常
1.声明一个变量rowtype
vrow emp%rowtype
2.声明一个自定义的异常
no_emp exception;
begin
2.查询员工信息,保存起来
select * into vrow from emp where empno=8888;
if vrow.sal is null then
raise no_emp; 抛出自定义的异常
end if;
exception
when no_emp then
dbms_output.put_line('输出了其他异常'||salerrm)
end;
查询指定编号的员工,如果没有找到,则抛出自定义的异常
游标来判断
$found $notfound
声明一个游标
声明一个变量,记录数据
从游标中取记录
如果有则 不管它
如果没有就抛出自定义的异常
declare
声明游标
curreor vrow is select * from emp where empno=8888;
声明一个记录型的变量
vrow emp$rowtype;
声明一个自定义异常
no_emp exception;
begin
打开游标
open vrows;
取数据
fetch vrows into vrow;
判断 游标是否有数据
if vrows%notfound then;
raise no_emp;
end if;
close vrows;
exception
when no_emp then
dbms_output.put_line('发生了自定义的异常');
emd;
存储过程:实际是封装在服务器上的一段plsql的代码片段
1.客户端去调用存储过程,执行效率就会非常高
2.语法:create[or replace] procedure 存储过程的名称
(参数名 in|out 参数类型)is | as
声明变量
begin
业务逻辑
end;
User user=new User();
public void getUser(int userid,user){
--
user.setName();
}
给指定员工涨薪,并打印涨薪前和涨薪后的工资
参数 :in 员工编号
参数:int 涨多少
声明一个变量:存储涨工资前的工资
查询出当前的工资是多少
打印涨薪前的工资
更新工资
create or replace procedure prcc_updatesal(vempno in number,vnum in number)
is
--声明变量,记录当前工资
vsal number;
begin
查询当前的工资
select sal into vsal from emp where empno=vempno;
输出当前涨薪前的工资
dbms_output.put_line('涨薪前:'||vsal);
更新工资
update emp set sal=vsal +vnum where empno=vempno;
输出涨薪后的工资
dbms_output.put_line('涨薪后:'||vsal+vnum);
提交
commit;
end;
打印涨薪后的工资
方式1
call proc_updatesal(7788,10);
方式2 用的最多的方式
declare
begin
proc_updatesal(7788,10);
end;
存储函数:实际上是一段封装是oracle服务器中的一段plsql代码片段,它是已经编译好的
语法:
create(or replace) function 存储函数的名称(参数名 in|out 参数名 in|out)
is | as
begin
end;
存储过程和存储函数的区别:
他们本质上没有区别
函数存在的意义是给过程来调用的 存储过程里面调用存储函数
默认是 in
查询指定员工的年薪
参数:员工的编号
返回:年薪
create or replace function func_getsal(vempno number)return number
is
声明变量,保存年薪
vtotalsal number;
begin
select sal*12 +nvl(comm,0) into vtotalsal from emp where empno=vempno;
return vtotalsal;
end;
调用存储函数
declare
vsal number;
begin
vsal := func_getsal(7788)
dbms_output.put_line(vsal);
en;
查询员工的姓名,和他的年薪
select ename,func_gctsal(cmpno) from emp;
函数可以在sql语句中直接调用
存储过程能实现的,存储过程能实现的,存储函数也能实现,存储函数能实现的
存储过程也能实现
查询员工指定员工的年薪--存储过程来实现
输出:年薪
create or replace procedure proc_gettotalsal(empno in_number,vtotalsal out number)
is
begin
select sal*12 +nvl(comm,0) into vtotalsal from emp where empno=vempno;
end;
declare
begin
proc_gettotalsal(7788,vtotal);
dbms_output.put_line('年薪:'||vtotal)
end;
java调用存储过程
jdbc的开发步骤
1.导入驱动包
2.注册驱动
3.获取连接
4.获取执行sql的statement
5.封装参数
6,执行sql
7获取结果
8.释放资源
触发器
当用户执行了insert | update |delete 这些
操作之后,可以出发一系列其他的动作
triger trigerhandler
作用:
在动作执行之前或者之后,出发业务处理逻辑
插入数据,做一些校验
语法:
create[or replace] triger 触发器的名称
before | after
insert | update |delete
on 表名
(for each row)
declare
begin
end;
新员工员工入职之后,输出一句话:欢迎加入黑马程序员
create or replace trigger tri_test1
after
insert
on emp
declare
begin
dbms_output.put_line('欢迎加入黑马程序员')
end;
insert into emp(empno,ename) values(9527,'huaan');
--数据校验,星期六老板不在,不能办理新员工入职
--在插入数据之前
--判断当前日期是否是周六
如果是周六,就不能拿插入
create or replace trigger tri_test2
before
insert
on emp
declare
--声明变量
vday varchar2(10);
begin
--查询当前
end;
select trim(to_char(sysdate,'day'))into vday from dual;
--判断当前日期
if vday='saturday' then
dbms_output.put_line('老板不在,不能办理入职')
--抛出系统异常
raise_application_error(-20001,'老板不在,不能办理入职');
end if;
end;
insert into emp(empno,ename) values(9527,'huaan');
触发器的分类
语句级触发器:不管影响多少行,都只会只会执行一次
行级触发器: 影响多少行,就触发多少次
:old.sal 100 代表旧的记录
:new 代表的是新的记录
--更新所有的工资 输出一句话
create or replace trigger tri_test3
after
update
on emp
for each row
declare
begin
dbms_output.put_line('更新了数据')
end;
update emp set sal=sal+10;
判断员工涨工资后的工资一定要大于涨工资前的工资
200--100
触发器 :before
旧的工资
新的工资
如果旧的工资大于新的工资,抛出异常,不让它执行成功
create or replace trigger tri_updatesal
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;
select * from emp;
update emp set sal=sal-100;