当前位置:Gxlcms > 数据库问题 > 四、Oracle loop循环、while循环、for循环、if选择和case选择、更改读取数据、游标、触发器、存储过程

四、Oracle loop循环、while循环、for循环、if选择和case选择、更改读取数据、游标、触发器、存储过程

时间:2021-07-01 10:21:17 帮助过:24人阅读

loop
执行的语句;
exit when 条件;
end loop;

declare
  --声明部分
  i number;
begin
  --代码开始

  i := 1;
  loop
    --循环开始
    dbms_output.put_line(i); --输出语句
    i := i + 1;
    exit when i = 10;
  end loop; --循环结束

end; --结束部分

 

案例2:while循环语法:

while 条件 loop
执行的语句;
end loop;

declare
  --声明部分
  i number;

begin
  --代码开始

  i := 1;
  while i < 20 loop
    --循环开始
    dbms_output.put_line(i); --输出语句
    i := i + 1;
  end loop; --循环结束

end; --结束部分

 

案例3:for循环语法:

for 变量 in 范围 loop
执行的语句;
end loop;

declare
  --声明部分
  i number;

begin
  --代码开始

  for i in 1 .. 30 loop
    --循环开始
    dbms_output.put_line(i); --输出语句
  end loop; --循环结束

end; --结束部分

 

案例4:根据老师的薪水输出不同的语句!

  if选择结构 和 case选择结构

-- 根据teacher表中的sal 来输出不同的语句
declare
  t_name   teacher.tname%type; --说t_name的类型根据teacher表中tname的类型来决定
  t_sal    teacher.sal%type;
  t_result varchar2(50);
begin
  --开始
  select tname, sal into t_name, t_sal from teacher where tno = 1002; --查询指定老师的薪水

  if t_sal > 5000 and t_sal < 10000 then
    -- 多重if
    t_result := 一级;
  elsif t_sal >= 10000 and t_sal < 20000 then
    t_result := 二级;
  else
    t_result := 高级;
  end if;
  --根据t_result的值来判断输入语句    switch
  case t_result
    when 一级 then
      dbms_output.put_line(哈哈....);
    when 二级 then
      dbms_output.put_line(一般般....);
    when 高级 then
      dbms_output.put_line(可以啊....);
  end case;
end; --结束

 

案例5: 函数  ==》把身份证号中的出生年月日隐藏!

create or replace function fn_teacher_tid(f_tid varchar2)
  return varchar2 --创建一个函数  传递一个varchar2类型的值 返回一个varchar2类型的值
is f_result varchar2(50); --声明变量
begin
  --开始书写函数内容
  if length(f_tid) != 18 then
    dbms_output.put_line(身份证格式不正确);
  else
    dbms_output.put_line(身份证格式正确);
  end if;
  f_result := substr(f_tid, 1, 6) || ******** || substr(f_tid, 15);
  return f_result;

end fn_teacher_tid; --函数结束

 

--调用函数
select fn_teacher_tid(110101198705256045) from dual;

 

案例6: 游标 :

01.是oracle系统给我们用户开设的一个数据缓冲区!
02.存放的是sql语句执行的结果集!
03.每个游标区都有一个名称,用户通过游标逐行获取需要的数据!


分类:
01.隐式游标: 非查询语句
只要我们使用pl/sql,程序在执行sql语句的时候 自动创建! 游标区===》sql
02.显示游标: 返回多行记录
03.REF游标(动态游标): 处理运行时才能确定的动态sql查询结果

游标的常用属性:
01.sql%found 影响了一行或者多行数据 返回true
02.sql%notfound 没有影响行 返回true
03.sql%rowcount 返回true影响行数
04.sql%isopen 游标是否打开!始终是false


使用游标的步骤:
01.声明游标
02.打开游标
03.使用游标获取记录
04.关闭游标

01.隐式游标

begin
  --  隐式游标    自动创建
  update teacher set tname = 大家辛苦了 where tno = 1002; --修改
  if sql%found then
    dbms_output.put_line(教师的信息已经更改 || sql%rowcount);
  else
    dbms_output.put_line(更改失败);
  end if;
end;

 

02.显示游标

declare
  --声明 显示游标
  c_tname teacher.tname%type;
  c_sal   teacher.sal%type;
  cursor teacher_cursor is
    select tname, sal from teacher where tno < 1005; --游标数据来源
begin
  open teacher_cursor; --打开游标
  fetch teacher_cursor
    into c_tname, c_sal; --使用游标
  while teacher_cursor%found loop
    dbms_output.put_line(教师的姓名是==》 || c_tname);
    dbms_output.put_line(教师的薪水是==》 || c_sal);
    fetch teacher_cursor
      into c_tname, c_sal; --逐行读取  
  end loop;
  close teacher_cursor; --关闭游标
end;

 

案例7:触发器

  触发器是针对于增删改!

update :old :new
insert :new
delete :old


:old 代表修改之前的值
:new 代表修改之后的值

select * from teacher t  for update

 

-- 创建一个用于保存teacher操作记录的表
create table teacher_log(logid number not null, old_value varchar2(150), create_date date, log_type number, t_no number);

 

--创建主键
alter table teacher_log add constraint pk_teacher_logid primary key(logid);

 

-- 创建序列
create sequence sq_teacherLog_logid minvalue 1 maxvalue 99999999999 start
  with 1 increment by 1;

 

--  创建触发器
create or replace trigger tr_teacher after insert or update or delete --会在增删改之后 触发
on teacher for each row --作用在teacher表中的每一行
declare --声明变量
old_value teacher_log.old_value%type;
log_type teacher_log.log_type%type;
t_no teacher_log.t_no%type;
begin
  if inserting then
    log_type  := 1; --新增
    t_no      := :new.tno;
    old_value := :new.tname || ***** || :new.sal;
  elsif deleting then
    log_type  := 2; --删除
    t_no      := :old.tno;
    old_value := :old.tname || ***** || :old.sal;
  else
    log_type  := 3; --修改
    t_no      := :old.tno;
    old_value := :old.tname || ***** || :old.sal || 现在的薪水: || :new.sal;
  end if;

  --把用户修改的数据 放入 teacher_log
  insert into teacher_log
  values
    (sq_teacherLog_logid.nextval, old_value, sysdate, log_type, t_no);
end tr_teacher; --结束

 

案例8:存储过程
为了完成一个特定的功能而实现编写一组sql语句的集合!

新增教室时,如果身份证号码不足18位,报错!

create or replace procedure pro_addTeacher --存储过程
(p_no teacher.tno%type, p_name teacher.tname%type, p_tid teacher.tid%type) is ex_tidException exception; --异常类型

begin
  if length(p_tid) != 18 then
    raise ex_tidException; --抛出异常
  end if;

  --新增
  insert into teacher (tno, tname, tid) values (p_no, p_name, p_tid);
  commit; --- 自动提交

exception
  -- 异常处理部分
  when ex_tidException then
    dbms_output.put_line(身份证号不正确);
  when others then
    dbms_output.put_line(其他异常);
  
end pro_addTeacher; --结束

 

--调用存储过程
call pro_addTeacher(1111, 小白白, 1122222222222222222);

 

name teacher.tname%type :会根据表中字段的类型,自动改变!

teacherRow teacher%rowtype: 一整行的记录,包括很多字段!

teacherRow.name

 

四、Oracle loop循环、while循环、for循环、if选择和case选择、更改读取数据、游标、触发器、存储过程

标签:close   ddt   result   包括   触发器   老师   seq   delete   保存   

人气教程排行