---------------------------Oracle day04----------------------------------
--01.什么是PL/SQL?
通俗理解:plsql:Procedure language sql 过程化语言
plsql是一组sql语句集合,在这个plsql中集合语句中可以处理复杂业务逻辑
(申明变量、条件分支、循环语句、异常处理)
优点:如果使用plsql语言,编写存储过程 函数,提供java代码调用,减少访问数据频率
缺点:对程序员要求比较高(高级程序员 或 专业DBA),存储过程 函数 移植不方便
--02.PL/SQL基本语法
declare
--声明变量 (普通变量、常量、引用型变量、记录型变量)
begin
--DML语句(逻辑语句)
end;
--03.普通变量和常量使用
--类似于java中 private String myname ="老王";
declare
myname varchar2(30) :='老王';
begin
myname := '隔壁老王';
select e.ename into myname from emp e where e.empno = '7369';
--打印变量
dbms_output.put_line(myname);
end;
--类似于java中private final String myname ="老王";
declare
myname constant varchar2(30) :='老王';
begin
--myname := '隔壁老王';
--打印变量
dbms_output.put_line(myname);
end;
--04.引用型变量 --emp.ename%type(推荐使用这种方式)
declare
myname emp.ename%type :='老王';
begin
select e.ename into myname from emp e where e.empno = '7369';
--打印变量
dbms_output.put_line(myname);
end;
--05.记录型变量
declare
v_row emp%rowtype;
begin
select * into v_row from emp e where e.empno = '7369';
--打印变量
dbms_output.put_line(v_row.empno||'=='||v_row.ename);
end;
--06.条件分支
语法:
if 条件 then
--语句
end if;
if 条件 then
--语句
else
--语句
end if;
if 条件 then
--语句
elsif 条件 then
--语句
else
--语句
end if;
--07.根据输入的年龄判断小于18输出未成年人,18-60成年人,60以上老年人
declare
v_age number(10):=&age;
begin
if v_age < 18 then
dbms_output.put_line('未成年人');
elsif v_age < 60 then
dbms_output.put_line('成年人');
else
dbms_output.put_line('老年人');
end if;
end;
--08.loop循环
语法:
for 变量名 in 起始值..结束值---(不用指定条件退出循环)
loop
--语句
end loop;
loop --需要执行条件退出循环
--通过条件退出循环
exit when 条件;
end loop;
while 条件 --需要设置条件
loop
--语句
end loop;
--09.输出1到100的数字
declare
begin
for i in 1..100
loop
dbms_output.put_line(i);
end loop;
end;
declare
v_number number:= 1;
begin
loop
exit when v_number > 100;
dbms_output.put_line(v_number);
v_number := v_number +1;
end loop;
end;
declare
v_number number:= 1;
begin
while v_number <=100
loop
dbms_output.put_line(v_number);
v_number := v_number +1;
end loop;
end;
--10.游标 cursor
什么是游标?
定义游标用于接收多条数据
语法:
定义游标:cursor 游标名称[(参数名 数据类型)] is select 查询语句;
使用游标:
open 游标名称[(参数名 数据类型)];
loop
--从游标中取出一条数据放入记录型变量
fetch 游标名称 into 记录型变量
--语句
--游标没有数据则退出
exit when 游标名称%notfound;
end loop;
close 游标名称;
--11.通过游标输出emp表中所有员工的信息
declare
--定义一个游标
cursor c_emp is select * from emp;
v_row emp%rowtype;
begin
open c_emp;--打开游标
loop --循环
fetch c_emp into v_row;--取出游标一条数据放入记录型变量中
exit when c_emp%notfound;--退出游标循环
dbms_output.put_line(v_row.empno || '=='|| v_row.ename);--打印
end loop;
close c_emp;--关闭
end;
--12.通过游标输出指定部门的员工信息
declare
--定义一个游标
cursor c_emp(v_deptno emp.deptno%type) is select * from emp where deptno = v_deptno;
v_row emp%rowtype;
begin
open c_emp(&deptno);--打开游标
loop --循环
fetch c_emp into v_row;--取出游标一条数据放入记录型变量中
exit when c_emp%notfound;--退出游标循环
dbms_output.put_line(v_row.empno || '=='|| v_row.ename);--打印
end loop;
close c_emp;--关闭
end;
--13.异常
异常用来增强程序健壮性和容错性
oracle中异常分为两类:
自带异常(预定义异常)
自定义异常
--除以0的异常plsql程序 自带异常(预定义异常)
declare
v_number number;
begin
v_number :=10/0;
exception when ZERO_DIVIDE then
dbms_output.put_line('除数不能为0');
end;
--一个变量容量不够时异常plsql程序 自带异常(预定义异常)
declare
v_number number(1);
begin
v_number :=20;
exception when VALUE_ERROR then
dbms_output.put_line('容量不够异常');
end;
--根据输入年龄判断,如果年龄大于150,抛异常
--自定义异常
语法:
定义异常 变量名称 exception;
declare
myexception exception;--定义异常变量
v_age number(10):=&age;--定义年龄变量
begin
if v_age > 150 then --自定义的业务异常
raise myexception;--抛异常
end if;
exception when myexception then --捕获异常
dbms_output.put_line('活不到150');
end;
--------------------------存储过程------------------
--14.存储过程
存储过程是在大型数据中,一组为了完成特定sql语句集。
存储过程名称 可以有输入参数 输出结果
存储过程可以编写非常复杂业务逻辑,实际可以替换java代码中业务逻辑
语法:
create [or replace] procedure 存储过程名(参数名 [in] 数据类型,参数名 out 数据类型)
is|as
--定义变量(普通变量 常量 记录型变量 引用型变量)
begin
--DML语句 (业务逻辑sql语句)
end;
--使用存储过程,输出指定员工的年薪
create or replace procedure pro_emp(v_empno in emp.empno%type)
is
--定义一个变量接收员工年薪 打印到output窗口
v_sal emp.sal%type;
begin
select sal*12+nvl(comm,0) into v_sal from emp where empno = v_empno;
dbms_output.put_line(v_sal);
end;
--通过plsql工具Test进行测试
--通过plsql过程语言测试存储过程
declare
begin
pro_emp(7369);
end;
--指定员工的年薪,用out参数返回年薪(工作中)
create or replace procedure pro_emp(v_empno emp.empno%type,out_sal out emp.sal%type)
is
begin
select sal*12+nvl(comm,0) into out_sal from emp where empno = v_empno;
end;
--测试
declare
--定一个变量来接收out返回结果
out_sal emp.sal%type;
begin
pro_emp(7369,out_sal);
dbms_output.put_line(out_sal);
end;
--15.函数(自定义函数)
存储过程和函数区别:
1.存储过程没有return 返回值 函数一定return返回值
2.存储过程 函数都有输入和输出参数 但函数中输出参数一般不用,使用return返回结果
3.函数可以有参数 也可以没有参数
4.存储过程可以有参数 也没有参数
5.存储过程可以没有out返回值,但是那这么定义就没有任何意义。
6.函数都是被存储过程调用
oracle多行函数 单行函数 to_char('xxx')
---语法
create [or replace] function 函数名称(参数名 数据类型,参数名 out 数据类型)
return 返回值的数据类型
is|as
begin
end;
--计算某个员工年薪并返回
create or replace function fun_emp(v_empno emp.empno%type)
return number
is
--接收年薪变量
v_sal number;
begin
select sal*12+nvl(comm,0) into v_sal from emp where empno = v_empno;
return v_sal;
end;
--测试
declare
v_sal number;
begin
v_sal := fun_emp(7369);
dbms_output.put_line(v_sal);
end;
--一般函数都是提供给存储过程调用
create or replace procedure pro_emp(v_empno emp.empno%type,out_sal out emp.sal%type)
is
begin
--select sal*12+nvl(comm,0) into out_sal from emp where empno = v_empno;
select fun_emp(v_empno) into out_sal from dual;
end;
--重要
--统一开发环境 eclipse 4.5.2 jdk1.7
--新建一个空的工作空间 修改字体大小 以及 jsp编码
--16.通过java代码测试jdbc连接
/**
* 根据员工编号查询员工信息 (测试连接oracle数据库)
*/
public static void findEmpByEmpno(Long empno) {
Connection conn = null;
PreparedStatement prepareStatement = null;
ResultSet rs = null;
// 获取连接
try {
conn = BaseDao.getConn();
// 预处理对象
prepareStatement = conn.prepareStatement(