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;


























原文地址:https://www.cnblogs.com/jerryyj/p/9621577.html