--PL/SQL实例
/*
declare
声明变量,初始化变量,声明游标
begin
执行部分
exception
异常捕获部分
end;
*/
declare
--声明变量
out_text varchar2(20);
i integer;
begin
out_text := '程序输出222';
i := 1/0;
dbms_output.put_line(out_text);
exception
--出现异常之后执行
when others then
dbms_output.put_line('出现了一个异常');
end;
select * from emp;
--嵌套执行PL/SQL块
declare
out_text varchar2(20);
begin
out_text := '外层PL/SQL块';
dbms_output.put_line(out_text);
--嵌套
declare
inner_text varchar2(20) := '内层PL/SQL块';
begin
dbms_output.put_line(inner_text);
end;
end;
--常用的运算符
declare
x number := 10;
y number := 20;
z number;
begin
z := x*y;
dbms_output.put_line('x*y='||z);
end;
declare
ename varchar2(20) := 'tom';
begin
ename := ename||'cat';
dbms_output.put_line(ename);
end;
--通过select ... into 语句对变量进行赋值,使用该语句对变量进行赋值时,语句查询结果不能是零行或多行(有且仅有一行)
declare
v_ename varchar2(20);
begin
select ename into v_ename from emp where empno=7943;
dbms_output.put_line(v_ename);
end;
--%rowtype和%type的使用
--%rowtype:将数据库表中的一行数据作为类型,在赋值时,需要查询出对应列数的数据进行赋值
declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno=7943;
dbms_output.put_line('员工姓名:'||v_emp.ename||',职位:'||v_emp.job);
end;
--%type:将表中一列作为类型
declare
v_ename emp.ename%type;
begin
select ename into v_ename from emp where empno=7369;
dbms_output.put_line(v_ename);
end;
--记录类型
/*
type 类型名 is record(
type1 数据类型,
type2 数据类型,
...
);
*/
declare
--定义类型
type emp_type is record(
empno emp.empno%type,
ename emp.ename%type,
sal emp.sal%type,
job emp.job%type
);
--定义该类型的变量
employee emp_type;
begin
select empno,ename,sal,job into employee from emp where empno=7943;
dbms_output.put_line(employee.empno||' '||employee.ename||' '||employee.sal||' '||employee.job);
end;
/*
PL/SQL中的流程控制语句
顺序结构
选择结构
循环结构
*/
--IF ... THEN end if;
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno=7934;
--对薪资进行判断,然后更新奖金列
if v_sal>4000 then
update emp set comm=100 where empno=7370;
elsif v_sal <2000 then
update emp set comm=500 where empno=7370;
else
update emp set comm=200 where empno=7370;
end if;
commit;
end;
-- case when then 类似于java中的switch
declare
v_grade varchar2(2);
begin
v_grade := upper('&asd');
case v_grade
when 'A' then
dbms_output.put_line('优');
when 'B' THEN
dbms_output.put_line('中');
when 'C' THEN
dbms_output.put_line('差');
else
dbms_output.put_line('滚出去');
end case;
end;
--PL/SQL循环结构
--loop ... end loop
-- 1+2+3....+100
declare
i number := 0;
v_sum number := 0;
begin
--无限循环
loop
v_sum := v_sum + i;
i := i + 1;
--给无限循环指定出口
if i>100 then
exit;
end if;
dbms_output.put_line(i);
end loop;
dbms_output.put_line(v_sum);
end;
--while循环
declare
i number := 0;
v_sum number := 0;
begin
while i<=100 loop
v_sum := v_sum + i;
i := i + 1;
end loop;
dbms_output.put_line(v_sum);
end;
--for
declare
i number := 1;
v_sum number := 0;
begin
-- 1..100 会自动增长,默认情况是从小到大,如果需要从大到小需指定reverse属性
for i in reverse 1..100 loop
v_sum := v_sum + i;
dbms_output.put_line(i);
end loop;
dbms_output.put_line(v_sum);
end;
--动态sql
/*
execute immediate 动态sql字符串 [into 变量名] [using 参数列表]
*/
declare
v_ename varchar2(20) := 'tom';
v_job varchar2(20) := 'dba';
v_empno number := 7942;
begin
--相当于jdbc update emp set ename=:name
execute immediate 'update emp set ename=:1,job=:2 where empno=7943' using v_ename,v_job;
execute immediate 'select ename from emp where empno=:1' into v_ename using v_empno;
dbms_output.put_line(v_ename);
commit;
end;
--游标的使用
/*
使用游标的步骤:1.定义 2.打开 3.使用 4.关闭
*/
--静态游标
declare
cursor my_cursor is select empno,ename from emp;
--定义用于接收游标数据的变量
v_empno emp.empno%type;
v_ename emp.ename%type;
begin
--使用游标的%isopen属性判断游标是否打开
if not my_cursor%isopen then
--使用open关键字打开游标
open my_cursor;
end if;
--获取到游标中的第一行数据
loop
fetch my_cursor into v_empno,v_ename;
--数据取完之后需要退出循环
-- if my_cursor%notfound then
-- exit;
-- end if;
exit when my_cursor%notfound;
dbms_output.put_line(v_empno||' '||v_ename);
end loop;
--关闭游标
close my_cursor;
end;
--oracle为了简化游标的使用提供了游标的for循环
--隐式的打开了游标,使用fetch获取游标中的数据,关闭了游标
declare
cursor my_cursor is select * from emp;
begin
for employee in my_cursor loop
dbms_output.put_line(employee.empno||' '||employee.ename||' '||employee.sal||' '||employee.deptno);
end loop;
end;
--动态游标的使用
/*
语法:type 游标类型名 is ref cursor [return 返回值]
*/
declare
--定义一个强游标类型
type my_cursor_type is ref cursor return emp%rowtype;
--定义该游标类型的游标变量
my_cursor my_cursor_type;
--定义用于存储游标数据的变量
v_emp emp%rowtype;
begin
--打开游标
open my_cursor for select * from emp;
loop
fetch my_cursor into v_emp;
exit when my_cursor%notfound;
dbms_output.put_line(v_emp.empno||' '||v_emp.ename||' '||v_emp.sal);
end loop;
end;