• oracle pl/sql 几道基础的编程题


    今天学了pl/sql基础,做了几道基础的编程题,做个笔记,方便复习。如果有做错的地方或者有待改进的地方,欢迎指正,不胜感激。
    练习参考的数据库表为oracle中自带的employees表。

    1.求1~100之间素数

    declare
      m_flag boolean := true;
    begin
      for i in 1 .. 100 loop
        for j in 2 .. i - 1 loop
          if mod(i, j) = 0 then
            m_flag := false;
          end if;
        end loop;
        if m_flag then
          dbms_output.put_line(i);
        end if;
        m_flag := true;
      end loop;
    end;

    2.对所有JOB_ID为IT_PROG 薪水增加一倍.

    declare
        cursor cur_raise_it is select * from employees e where e.job_id='IT_PROG' for update;
    begin
        for i in cur_raise_it loop
            update employees e set e.salary=e.salary*2 where current of cur_raise_it;
        end loop;
    end;

    3.编写一个函数以检查所指定雇员的薪水是否有效范围内。不同职位的薪水范围为:
     JOB_ID  Range
     IT_PROG 5500-8500
     ST_CLERK 2501-3500
     SA_REP 7000-8500
     Others No operation.
     如果薪水在此范围内,则显示消息"Salary is OK",否则,更新薪水为该范围内的最小值。


    create or replace function check_sal(emp_no employees.employee_id%type)
      return varchar2 as
      v_job employees.job_id%type;
      v_sal employees.salary%type;
      v_msg varchar2(100) := 'Salary Is Ok';
    begin
      select e.job_id, e.salary
        into v_job, v_sal
        from employees e
       where e.employee_id = emp_no;
      if v_job = 'IT_PROG' then
        if v_sal not between 5500 and 8500 then
          update employees e set e.salary = 8500;
          v_msg := 'salary changes from ' || v_sal || ' to' || ' 5500';
        end if;
      elsif v_job = 'ST_CLERK' then
        if v_sal not between 2501 and 3500 then
          update employees e set e.salary = 3500;
          v_msg := 'salary changes from ' || v_sal || ' to' || ' 2501';
        end if;
      elsif v_job = 'SA_REP' then
        if v_sal not between 7000 and 8500 then
          update employees e set e.salary = 8500;
          v_msg := 'salary changes from ' || v_sal || ' to' || ' 7000';
        end if;
      else
        null;
      end if;
      return v_msg;
    end;

    --调用示例
    declare v_msg varchar2(100);
    begin
    v_msg:=check_sal(emp_no=>102);
    dbms_output.put_line(v_msg);
    end;

    4.对名字以"A"或"H"开始的所有雇员按他们的基本薪水的10%加薪。

    declare
    cursor cur_sal_raise is select * from employees e where substr(e.last_name,1,1) in('A','H');
    begin
        for emp_record in cur_sal_raise loop
            update employees e set e.salary = e.salary * 1.1 WHERE CURRENT OF emp_record;
        end loop;
    end;

    5.编写一PL/SQL,以提升两个资格最老的"职员"为"高级职员"。(按工作时间算)

    declare
      cursor cur_raise_old is
         select employee_id,
                first_name,
                last_name,
                email,
                job_id,
                hire_date,
                salary
           from (select e.employee_id,
                        e.job_id,
                        e.first_name,
                        e.last_name,
                        e.email,
                        e.hire_date,
                        e.salary,
                        months_between(sysdate, e.hire_date) months
                   from employees e
                  order by months desc) t
          where rownum <= 2 ;
    begin
          for i in cur_raise_old loop
             update employees e set e.job_id ='高职' where i.employee_id =e.employee_id;
          end loo
    p;
    end;

    6.编写存储过程检查如果已经雇佣该雇员超过60个月,则给他额外加薪3000.

    create or replace procedure pro_raise_old(emp_no in number) is
           v_hiredate employees.hire_date%type;
           v_sal employees.salary%type;
    begin
           select e.hire_date,e.salary into v_hiredate,v_sal from employees e where e.employee_id=emp_no;
           if months_between(sysdate,v_hiredate)>60 then v_sal:=v_sal+3000;
           end if;
           update employees e set e.salary=v_sal where e.employee_id=emp_no;
    end;
    --调用示例
    begin
       pro_raise_old(emp_no=>103);
    end;

    7.编程实现对所有雇员按他们基本薪水的10%加薪,如果所增加的薪水大于1000,则取消加薪.

    declare
      cursor cur_raise_two is
        select * from employees for update;
    begin
      for i in cur_raise_two loop
        if i.salary * 0.1 > 1000 then
          null;
        else
          update employees e
             set e.salary = e.salary*1.1
           where current of cur_raise_two;
        end if;
      end loop;
    end;

    8.A单价49,B单价39,C单价17,现有2000元,要购买A,B,C,请给出花费最接近2000元(<=2000元)的购买计划,打印出来。(今天上课时的课堂练习)

    DECLARE
      a            NUMBER := 49;
      b            NUMBER := 39;
      c            NUMBER := 17;
      total_amount NUMBER := 2000;
      a_qty        NUMBER;
      b_qty        NUMBER;
      c_qty        NUMBER;
      a_amount     number;
      b_amount     number;
      c_amount     number;
      l_max_amount NUMBER := 0;
    BEGIN
      FOR i IN 0 .. trunc(total_amount / a) LOOP
        FOR j IN 0 .. trunc(total_amount / b) LOOP
          FOR k IN 0 .. trunc(total_amount / c) LOOP
            IF a * i + b * j + c * k >= l_max_amount AND
               a * i + b * j + c * k <= total_amount THEN
              l_max_amount := a * i + b * j + c * k;
              a_amount     := i;
              b_amount     := j;
              c_amount     := k;
            END IF;
          END LOOP;
        END LOOP;
      END LOOP;
      dbms_output.put_line('a:' || a_amount);
      dbms_output.put_line('b:' || b_amount);
      dbms_output.put_line('c:' || c_amount);
      dbms_output.put_line('最接近的数字为:' || l_max_amount);
    END;


























  • 相关阅读:
    android绘画折线图二
    android绘画折线图一
    jQuery Select操作大集合
    jquery事件切换hover/toggle
    jquery $(document).ready() 与window.onload的区别
    canny边缘检测 C++手动实现
    高斯核原理和C++实现
    darknet-yolov3 burn_in learning_rate policy
    UserWarning: indexing with dtype torch.uint8 is now deprecated, please use a dtype torch.bool instead
    BatchNormaliation
  • 原文地址:https://www.cnblogs.com/jerryyj/p/9621577.html
Copyright © 2020-2023  润新知