plsql语句块:
set serveroutput on; //打开控制台输出的命令
语法:
declare
声明部分
begin
//执行部分
异常,事物,语句块等
end;
变量的类型
oracle变量类型,oracle数据类型:integer varchar2等
自定义数据类型
1. 定义和列的类型保持一致
v_sal emp.sal%type;-- 和emp表sal列的类型保持一致
2. 定义和表达类型保持一致
v_emp emp%rowtype; -- 和emp表的结构一致
3. 定义自己的封装类(对象)
--声明的是类型
type type_emp_name_sal is record(v_empname EMP.ENAME%type,v_empsal EMP.SAL%type);
--变量名是v_name_sal 类型是type_emp_name_sal
v_name_sal type_emp_name_sal;
4. 数组
--声明数组类型
type int_array is table of integer index by BINARY_integer;
--int类型数组的变量
v_numbers int_array;
流程控制语句
1. if语句
if v_id = 1 then
dbms_output.put_line(v_id);
elsif v_id = 2 then
dbms_output.put_line('elsif');
else
dbms_output.put_line(v_id);
end if;
2. switch语句 case 语句
case
when v_id = 1 then
dbms_output.put_line(v_id);
when v_id = 2 then
dbms_output.put_line('elsif');
else
dbms_output.put_line(v_id);
end case;
3. 循环语句
1. for循环
-- for循环
for v_i in reverse 1..10 loop
SYS.DBMS_OUTPUT.PUT_LINE(v_i);
end loop;
2. while循环
--while循环
while v_id < 10 loop
SYS.DBMS_OUTPUT.PUT_LINE(v_id);
--条件的改变
v_id := v_id + 1;
end loop;
3. loop循环
loop
SYS.DBMS_OUTPUT.PUT_LINE(v_id);
--条件的改变
v_id := v_id + 1;
exit when v_id = 10;
end loop;
4. 通过goto语句完成循环
<<a>>
SYS.DBMS_OUTPUT.PUT_LINE(v_id);
v_id := v_id + 1;
if v_id < 10 then
goto a;
end if;
输出菱形星号
*
***
*****
***
*
代码:
declare
kong integer := 0;
xing integer :=0;
begin
for i in 1..5 loop
--每行由空格和星号组成
if i < 4 then
-- 1. 上半
kong := 3 - i;
xing := 2 * i - 1;
else
-- 2.下半
kong := i - 3;
xing := -2 * i + 11;
end if;
--输出空格
for k in 1..kong loop
dbms_output.put(' ');
end loop;
--输出星号
for k in 1..xing loop
dbms_output.put('*');
end loop;
--换行
dbms_output.new_line();
end loop;
end;
案例练习
10个人围成圈,数到3退出圈,问最后退出的是谁 //数数问题 declare v_personNumber integer := 10;--人数 v_number integer := 3;--数的数
begin -- 把人放入数组中 for i in 1..v_personNumber loop v_data(fang) := i; fang := fang + 1; numbers := numbers + 1; end loop;
end;
plsql操作数据
分析:对emp集体涨工资,涨幅不一致, 1000以内 40% 1000-2000 30% 2000-3000 20 3000 10%
declare
-- 数据全部取出
--数组存放数据(相当于jdbc中的结果集封装)
--员工编号和员工的薪水
type type_empno_sal is record (v_empno EMP.empno%type,v_sal EMP.SAL%type);
--定义员工数组
type type_emps_list is table of type_empno_sal index by binary_integer;
--定义保存员工信息的容器
v_emps_no_sals type_emps_list;
v_rows integer;--存放多少条数据
begin
select count(1) into v_rows from emp;
--去员工表每行信息,存储到容器中
for r in 1..v_rows loop
select empno,sal into v_emps_no_sals(r - 1) from (select rownum num,emp.* from emp) e where e.num = r;
end loop;
for r in 1..v_rows loop
case
when v_emps_no_sals(r-1).v_sal <= 1000 then
update emp set sal = sal * 1.4 where empno = v_emps_no_sals(r-1).v_empno;
when v_emps_no_sals(r-1).v_sal > 1000 and v_emps_no_sals(r-1).v_sal <= 2000 then
update emp set sal = sal * 1.3 where empno = v_emps_no_sals(r-1).v_empno;
when v_emps_no_sals(r-1).v_sal > 2000 and v_emps_no_sals(r-1).v_sal <= 3000 then
update emp set sal = sal * 1.2 where empno = v_emps_no_sals(r-1).v_empno;
else
update emp set sal = sal * 1.1 where empno = v_emps_no_sals(r-1).v_empno;
end case;
end loop;
commit;
end;
游标
1.声明游标
2.打开游标
3.循环提前游标
4.关闭游标(释放游标占用的空间)
案例:游标实现降薪处理
declare
--声明游标
cursor v_emp_cur is select empno,sal from emp;
--信息封装
type type_empno_sal is record (v_empno EMP.empno%type,v_sal EMP.SAL%type);
v_temp_empno_sal type_empno_sal;
begin
-- 打卡游标
open v_emp_cur;
-- 循环提取游标
loop
--去当前游标所在行的数据
fetch v_emp_cur into v_temp_empno_sal;
--判断提取成功或失败
if v_emp_cur%found then
--游标有数据
-- SYS.DBMS_OUTPUT.PUT_LINE(v_temp_empno_sal.v_empno||'<>'||v_temp_empno_sal.v_sal);
case
when v_temp_empno_sal.v_sal > 3000 then
update emp set sal = sal * 0.6 where empno = v_temp_empno_sal.v_empno;
when v_temp_empno_sal.v_sal > 2000 and v_temp_empno_sal.v_sal<= 3000 then
update emp set sal = sal * 0.7 where empno = v_temp_empno_sal.v_empno;
when v_temp_empno_sal.v_sal > 1500 and v_temp_empno_sal.v_sal <= 2000 then
update emp set sal = sal * 0.8 where empno = v_temp_empno_sal.v_empno;
else
update emp set sal = sal * 0.99 where empno = v_temp_empno_sal.v_empno;
end case;
else
--游标提取完毕
exit;
end if;
commit;
end loop;
--关闭游标
close v_emp_cur;
end;
案例2:for循环与游标
declare
--声明游标
cursor cur_emp_no_sal(v_deptno emp.deptno%type) is select empno,sal from emp where deptno= v_deptno;
begin
--for循环提取游标
for v_empno_sal in cur_emp_no_sal(10) loop
SYS.DBMS_OUTPUT.PUT_LINE(v_empno_sal.empno||'<>'||v_empno_sal.sal);
end loop;
end;
异常处理
根据异常名字 exception when Too_many_rows then SYS.DBMS_OUTPUT.PUT_LINE('Too_many_rows'); when others then 注意:others只能写在最后面
根据错误代号 exception when others then case when sqlcode=-1476 then DBMS_OUTPUT.PUT_LINE('被0整除异常'); when sqlcode = -1422 then DBMS_OUTPUT.PUT_LINE('返回多条记录赋值'); else
-- SYS.DBMS_OUTPUT.PUT_LINE('出现异常了'||sqlcode||'<>'||sqlerrm); -- rollback;
自定义异常 declare my_exec exception; my_exec2 exception; --把自定义异常和错误代号绑定 pragma EXCEPTION_INIT (my_exec2, -9527); begin if 3 > 2 then --抛出异常 throw new 对象 raise my_exec2; end if; exception when my_exec then SYS.DBMS_OUTPUT.PUT_LINE('自定义异常'||sqlcode); when my_exec2 then SYS.DBMS_OUTPUT.PUT_LINE('自定义异常2<>'||sqlcode); when others then SYS.DBMS_OUTPUT.PUT_LINE('其他异常'); end;
4.自定义异常2
declare
my_exec exception;
my_exec2 exception;
pragma EXCEPTION_INIT (my_exec2, -9527);
begin
if 3 > 2 then
--抛出异常 throw new 对象 -20000 到 -20999
RAISE_APPLICATION_ERROR(-20000, '我的异常');
end if;
exception
when my_exec then
SYS.DBMS_OUTPUT.PUT_LINE('自定义异常'||sqlcode);
when my_exec2 then
SYS.DBMS_OUTPUT.PUT_LINE('自定义异常2<>'||sqlcode);
when others then
SYS.DBMS_OUTPUT.PUT_LINE('其他异常'||sqlcode);
end;