Oracle、PL_SQL经典练习题

时间:2022-08-03 22:54:14

---------------------------------------      1--5题   ----------------------------------------------------

--1.编写一个程序块,从emp表中显示名为“SMITH”的雇员的薪水和职位。

declare
   v_sal emp.sal%type;
   v_job emp.job%type;
   v_ename emp.ename%type := '&雇员名:';
begin
   select sal,job into v_sal,v_job from emp where ename = v_ename;
   DBMS_OUTPUT.put_line(v_sal||'-----'||v_job);   --拼接字符串
end;

 -- 2.编写一个程序块,接受用户输入一个部门号,从dept表中显示该部门的名称与所在位置。
declare
    v_dname dept.dname%type;
    v_loc   dept.loc%type;
    v_deptno dept.deptno%type := '&no';
begin
    select dname ,loc into v_dname,v_loc from dept where deptno =v_deptno;
    dbms_output.put_line(v_dname||'-----'||v_loc);
end;

select * from emp;
-- 3.编写一个程序块,利用%type属性,接受一个雇员号,从emp表中显示该雇员的整体薪水(即,薪水加佣金)。
declare
     v_empno emp.empno%type:='&no';
     v_sal   emp.sal%type;
     v_comm  emp.comm%type;
begin
      select sal , comm into v_sal,v_comm from emp where empno =v_empno;
      dbms_output.put_line(v_sal+nvl(v_comm,0));
end;
--  4.编写一个程序块,利用%rowtype属性,接受一个雇员号,从emp表中显示该雇员的整体薪水(即,薪水加佣金)。
declare
       v_empno emp.empno%type:= '&no';
       v_emp   emp%rowtype;
begin
       select sal , comm into v_emp.sal,v_emp.comm from emp where empno =v_empno;
       
       dbms_output.put_line(v_emp.sal+nvl(v_emp.comm,0));
end;
--  5.某公司要根据雇员的职位来加薪,公司决定按下列加薪结构处理:
--              Designation    Raise
              -----------------------
--              Clerk          500
--              Salesman       1000
--              Analyst        1500
--              Otherwise      2000
--编写一个程序块,接受一个雇员名,从emp表中实现上述加薪处理。
declare
       v_ename emp.ename%type :='&name';
       v_emp   emp%rowtype;
begin
       select empno ,job into v_emp.empno ,v_emp.job fROm emp where ename =v_ename;
       if v_emp.job='CLERK' then
       update emp set sal=sal+500 where empno = v_emp.empno;
       elsif v_emp.job='SALESMAN' then
       update emp set sal =sal+1000 where empno =v_emp.empno;
       elsif v_emp.job='ANALYST' THEN
       update emp set sal=sal+1500 where empno =v_emp.empno;
       else
       update emp set sal=sal+2000 where empno=v_emp.empno;
       end if;
       DBMS_OUTPUT.put_line('加薪成功');

end;


-------------------------------------------------知识点--------------------------------------------------------------------------

--条件语句  提示: ELSIF不能写成 ELSEIF
      1.--if  《布尔表达式》 then
        --end  if;
      
      2.--if 《布尔表达式》 then
        --     else
        --end if;
      
      3-- if 《布尔表达式》  then
      --     。。。。
      --  elsif《其他布尔表达式》then
      --     。。。。
      --  elsif 《其他布尔表达式》 then
      --     。。。。
      --  else
      --     。。。。
      --end if;


--case when 判断
       ------  格式 1  ------
    --v_manage :=?     --v_manage :=?要输出信息的变量  名字可变
    --  case 条件表达式       --? 要判断的变量
    --     when 条件表达式结果 then ?
    --     when 条件表达式结果 then ?
    --     。。。
    --     [else ?]   --可以写也可以 不写
    --  end;
    --
 ------  格式 2  ------
  --       case
    --     when 条件表达式1 then ?
    --     when 条件表达式2 then ?
    --     。。。
    --     [else ?]   --可以写也可以 不写
    --  end;
declare
       v_grade varchar2(2):='&g';
       v_manage varchar2(30);
begin
       v_manage :=
       case, v_grade
            when 'A' then '棒极了'
            when 'B' then '很好'
            when 'C' then '还可以'
            else '没有级别'
        end;
        DBMS_OUTPUT.put_line('老师的评语是:'||v_manage);
end;

-- 循环  
   --loop
   --
   --exit when ?     当 当满足?条件时 退出循环
   --end loop;

--循环 1---10;
declare
       i number(2) :=0;             --声明变量
begin
     
     loop                           --循环开始
          i:=i+1;                   -- 变量            
          dbms_output.put_line(i);
          exit when i=10;           --满足 条件   退出循环
     end loop;                      --结束循环
end;

-- while 循环
   -- while 条件 Loop
   --       dbms_output.put_line(x);
   --    变量
   -- end loop;
   

--循环 1---10;
declare
       x number(2) :=1;
begin
     while x<=10 Loop
           dbms_output.put_line(x);
           x:=x+1;
     end loop;
end;

--数字循环
          -- for 变量名 in 数字1..数字2 Loop
          --     循环体
          -- end loop;

begin
 for i in 1..10 Loop
     dbms_output.put_line(i);
     end loop;
end;
--------------------------------------------------------------------
-- 从 20输到25 又从25 输到20
create  table temp_table(t_num number);
drop table temp_table;
declare
       i number :=1 ;
begin
     --insert into temp_table (t_num) values(i);
     for i in  20 ..25 loop        
         insert into temp_table (t_num) values(i);
     end loop;
     --insert into temp_table (t_num) values(i);
     for i in reverse 20 ..25 loop                --   reverse 倒序
         insert into temp_table (t_num) values(i);
     end loop;
end;
select * from temp_table;


--  老师写的  -- 从 20输到25 又从25 输到20
CREATE TABLE temp_table(num_col NUMBER);

select * from temp_table;


DECLARE
    V_counter NUMBER := 10;
BEGIN
   INSERT INTO temp_table(num_col) VALUES (v_counter );
   FOR v_counter IN 20 .. 25 LOOP
      INSERT INTO temp_table (num_col ) VALUES ( v_counter );
   END LOOP;
   INSERT INTO temp_table(num_col) VALUES (v_counter );
   FOR v_counter IN REVERSE 20 .. 25 LOOP
      INSERT INTO temp_table (num_col ) VALUES ( v_counter );
   END LOOP;
END ;
----------------------------------------------------------------

-- 100-110 之间的素数;
declare
        v_i number(3) :=101; --外循环
        v_j number(3);       --内循环
        v_count number(2) :=0;       --素数个数
begin
     while v_i<110 loop
           v_j :=2;
           loop
               if mod(v_i,v_j)=0 then     --mod(i,j)相当于 i取余 j
                  v_j:=0;
                  exit;
               end if;
               v_j :=v_j+1;
               exit when v_j>v_i-1;
           end loop;
           
           if v_j>0 then
           dbms_output.put_line(''to_char(v_j));  --输出  的质数;
              v_count := v_count +1;
           end if;
           v_i :=v_i+2;
     end loop;
     dbms_output.put_line(to_char(v_count));      --  质数的个数
end;
--游标
      --cursor 游标名  is  sql查询语句 where rownum <=数;
      --通过  游标查询  emp表中 前 11行的  ename , sal;

declare
        cursor c_cursor is select ename,sal from emp where rownum<11;
        v_ename emp.ename%type;
        v_sal emp.sal%type;
begin
        open c_cursor;                        --打开 游标;
        fetch c_cursor into  v_ename ,v_sal;   --提取 游标;
        while c_cursor%found loop     --%found    判断存在; 不存在就跳出循环;
              dbms_output.put_line(v_ename||':'||v_sal);
              fetch c_cursor into v_ename ,v_sal; --提取 游标;
        end loop;
        close c_cursor;                            --关闭游标;
end;

--带参数的游标
declare
    cursor c_c1(cs_deptno  number) is
    select  dname,loc from dept where deptno<=cs_deptno;
    v_dname dept.dname%type;
    v_loc   dept.loc%type;
begin
     open c_c1(cs_deptno => 30 )  ;          -- 打开  用   =>  传值(参数)
     loop
         fetch c_c1 into v_dname,v_loc;
         exit when c_c1%notfound;           --  %notfound  当没找到时退出
         dbms_output.put_line(v_dname||'--------'||v_loc);
     end loop;
     close c_c1;                             --关闭 游标
end;

--游标例子3:给工资低于1200 的员工增加工资50
declare
       v_empno emp.empno%type;
       v_sal   emp.sal%type;
       cursor c_cursor is select empno,sal from emp ;
begin
     open c_cursor;
     loop
         fetch c_cursor into v_empno,v_sal;
         exit when c_cursor%notfound;         --%notfound     没找到  退出;
         if v_sal<1200 then
            update emp set sal=sal+50 where empno=v_empno;
            dbms_output.put_line('编号为'||to_char(v_empno)||'员工工资已更新!');
         end if;
         dbms_output.put_line('记录数:'||c_cursor%rowcount);     --%rowcount 记录数;
     end loop;
     close c_cursor;
end;

select* from emp where sal<1200;



--有参数且有返回值的游标。

declare
       type e_record is record(
         v_ename emp.ename%type,
         v_hiredate emp.hiredate%type
       );
       rec e_record;
       cursor c_c1(c_empno emp.empno%type) return e_record is select ename,hiredate from emp where empno =c_empno;
begin
     open c_c1(7369);
          loop
              fetch c_c1 into rec;
              if c_c1%found then
                 dbms_output.put_line(rec.v_ename||'::'||rec.v_hiredate);
              else
                dbms_output.put_line('处理完毕');
                exit;
              end if;
          end loop;
     close c_c1;
end;

--有参数  有返回值;

declare
       type rec_record is record(
            v_ename emp.ename%type,              --此处  后面用逗号;
            v_hiredate emp.hiredate%type
       );
       rec rec_record;
       cursor c_c1(v_empno emp.empno%type) return rec_record
        is  select ename , hiredate from emp where empno = v_empno;
begin
     open c_c1 (7369);
          loop
          fetch c_c1 into rec;
          if c_c1%found then
             dbms_output.put_line(rec.v_ename||'------'||rec.v_hiredate);
          else
              dbms_output.put_line('已经处理');
              exit;
          end if;
          end loop;
     close c_c1;
end;