游标,触发器,循环复习

----for循环---------------------------------------
FOR ... in ... LOOP
 END LOOP;

 BEGIN
   FOR i IN 1..10 LOOP
     dbms_output.put_line(i);
   END LOOP;
 END;

问题 150 ?
     3到40  ?
----while循环----------------------------------
WHILE ... LOOP
  END LOOP;

 declare
   n number(3) :=10;
 begin
   WHILE n>=0 LOOP
      dbms_output.put_line(n);
      n:=n-1;
   END LOOP;
 end;
/

问题 : 1 2 350
        2 4 6 8 10 
        15 16 17 18 19 。。。。 30
length('abc') --获取字符长度
select substr('abc',2,1) from dual;--从第2个字符开始截取1个



--使用 while 循环 将你的名字倒序输出
declare
  str varchar2(50):='包玉坤';
  len number(5);
  c char(2);
begin
  len := length(str);
  while len>0 loop
    c := substr(str,len,1);
    dbms_output.put_line(c);
    len := len-1;
  end loop;
end;
SQL> declare
  2    str varchar2(50):='包玉坤';
  3    len number(5);//计数
  4    c char(2);//
  5  begin
  6    len := length(str);//用length计算字符串长度=3
  7    while len>0 loop//条件:len>0
  8      c := substr(str,len,1);//截取字符串substr(‘字符’,‘从几位开始’,‘取几位’)=(‘暴雨坤’,’3‘,’1‘)坤
  9      dbms_output.put_line(c);//输出c
 10      len := len-1;//每循环一次减一
 11    end loop;
 12  end;
 13  /
declare
  str varchar2(50):='春天不洗澡处处蚊子咬请洒敌敌畏蚊子全死了';
  len number(5);
  c char(2);
begin
  len := length(str);
  while len>0 loop
    c := substr(str,len,1);
    dbms_output.put_line(c);
    len := len-1;
  end loop;
end;
-------------------------------------------------

触发器
create table Disney
(
id number primary key,
data varchar2(10)
);

create sequence id_seq;
create or replace trigger bifer_disney_id_pk
beFORe insert
on Disney
FOR each row
begin
select id_seq.nextval into :new.id FROM dual;
end;
/

insert into Disney(data) VALUES('tom');
insert into Disney(id,data) VALUES('6','jerry');

select * from Disney;
----------------------------------------------
电话记录表PHONE_DETAIL
--主键ID
--电话号码PHONE_NO
--记录时间CREATE_TIME (使用当前系统时间)
--通话时长(分钟)DURATION
--通话资费类型COST_ID
--通话费用COST (单价*时长)
create table phone_detail(
  id number(11) primary key,
  phone_no varchar2(20),
  create_time date,
  duration number(10),
  cost_id number(11),
  cost number(11,2)
);
create sequence phone_seq;


服务资费表PHONE_COST
--资费类型COST_ID
--资费名COST_NAME
--单价(元/分钟)COST_PRICE
--number(5,2)五位数,两位小数
create table phone_cost(
  cost_id number(11) primary key,
  cost_name varchar2(20),
  cost_price number(5,2)
);
insert into phone_cost
   values (1,'A资费',1.5);
insert into phone_cost
   values (2,'B资费',0.5);
insert into phone_cost
   values (3,'C资费',0.3);

需求:当向PHONE_DETAIL表中插入记录
时,采用触发器自动计算出通话费用
COST字段值写入。
 
 insert into PHONE_DETAIL
 (id,phone_no,duration,
  cost_id,create_time)
 values (phone_seq.nextval,
   '13111111112',8,3,sysdate);

 上述insert执行后,自动计算出cost值写入
 =====触发器=======
create or replace trigger cost_trigger
before insert on PHONE_DETAIL
for each row
declare
 v_price number(7,2) :=0;
 v_cost number(7,2) :=0;
begin
    select cost_price into v_price
    from phone_cost 
    where cost_id=:NEW.cost_id;
    v_cost := v_price*:NEW.duration;
    :NEW.cost := v_cost;
end;
/
//覆盖掉原来记录new
------------------------------------
4)触发器
  触发器不用显式调用,是由一些
数据库操作自动触发。例如insert,
update,delete等动作触发,也可以
由登录或登出等事件触发。
  触发器分类:
   *a.DML触发器
     由DML语句操作触发.DML触发器
   又分为语句级触发器和行级触发器。
   语句级:对表执行insert,delete,
     update时触发调用一次。
   行级:每行记录调用一次触发器功能
    行级触发器可以获取当前操作的记录

   b.系统触发器
     由系统事件触发,比如登录,登出
  
  DML触发器创建格式:
create or replace trigger 触发器名
before|after ?事件类型 ondeclare
 --定义区
begin
 --主处理区
exception
 --异常处理区
end;
/


--查7499的津贴
declare
  v_name varchar2(10);
  v_sal number(7,2);
begin
  select ename,sal 
  into v_name,v_sal
  from emp 
  where empno=7499; 
  dbms_output.put_line('姓名:'||v_name);
  dbms_output.put_line('工资:'||v_sal);
end;
/
--7499的入职日期
declare
  v_name varchar2(10);
  v_sal number(7,2);
  v_job emp.job%type ;
  v_HIREDATE  emp.hiredate%type;
begin
  select ename,sal,hiredate,job 
  into v_name,v_sal,v_HIREDATE,v_job
  from emp 
  where empno=&n; 
  dbms_output.put_line('职员姓名:'||v_name);
  dbms_output.put_line('工资:'||v_sal);
  dbms_output.put_line('入职日期:'||v_HIREDATE);
  dbms_output.put_line('工作:'||v_job);
end;

  游标
  什么时候用?
   用于提取表中多行记录
   单行使用select ... into...
  怎么定义? 
   CURSOR 名称 IS select语句;
  怎么用?
   OPEN 游标名;
   fetch 游标名 into 变量
   CLOSE 游标名;
   利用游标名%NOTFOUND结束循环.
   fetch 游标名 into 变量
   exit when 游标名%NOTFOUND;
   --数据处理
declare
   CURSOR c_emp_cursor IS
      select ename,sal from emp;
   v_name varchar2(10);
   v_sal number(7,2);
 begin
   OPEN c_emp_cursor;
   loop
     FETCH c_emp_cursor 
       INTO v_name,v_sal;
     exit when c_emp_cursor%NOTFOUND;
     dbms_output.put_line(v_name||v_sal);
   end loop;
   CLOSE c_emp_cursor;
 end;

-------------作业p179---------------------
--编写pl/sql块,根据输入的部门编号统计部门内的员工总人数
declare 
  n_deptno number;
  n_total number;
  no_dept exception;
begin
  n_deptno:=&n;
  select count(deptno) into n_total
from emp where deptno=n_deptno;
if n_total=0 then
  raise no_dept;
else
  dbms_output.put_line(n_deptno||'部门的总人数为'||n_total);
end if;
exception
  when no_dept then dbms_output.put_line('此部门不存在');
end;
--if条件分支控制语句。工作时间满15年增加1000元薪水,10-15增加500元,少于10增加200元
declare
  n_hire number(6,2);
  n_empno number;
begin
  n_empno:=&n;
  select months_between(sysdate,hiredate)into n_hire from emp where empno=n_empno;
  if n_hire>=360 then
  Update emp set sal=sal+1000 where empno=n_empno;
  elsif n_hire>=240 then
  Update emp set sal= sal+500 where empno=n_empno;
  else Update emp set sal=sal+300 where empno=n_empno;
end if ;
end;

set serveroutput on
--用for循环打印三角形
begin
  for i in 1..10
loop
    for j in 1..i
loop
      dbms_output.put('*');
   end loop;
   dbms_output.put_line('');
  end loop;
 end;


--附加1:
declare --定义变量部门,总人数,
  n_deptno number;
  n_total number;
  no_dept exception;
begin
  n_deptno:=&n;


  select count(deptno) into n_total
from emp where deptno=n_deptno;
if n_total=0 then
  raise no_dept;
else
  dbms_output.put_line(n_deptno||'部门的总人数为'||n_total);
end if;
exception
  when no_dept then dbms_output.put_line('此部门不存在');
end;

--附加2:
declare
  n_deptno number;
begin
  n_deptno:=&n;
  if n_deptno=10 then
  Update emp set sal=sal+100 where deptno=n_deptno;
  elsif n_deptno=20 then
  Update emp set sal= sal+50 where deptno=n_deptno;
  elsif n_deptno=20 then
  Update emp set sal=sal+30 where deptno=n_deptno;
  end if ;
end;
--附加3:
decale 
 a_num int:=1;

begin
  for i in 1..6 loop
    a_num :=a_num*i;
    
   end loop;
   dbms_output.put_line(a_num);
 end;

 

posted @ 2024-04-09 22:43  困到很想醒  阅读(7)  评论(0编辑  收藏  举报