存储过程

 --匿名块
 --存储过程
 --1.无参存储过程
 CREATE OR REPLACE PROCEDURE proc_1 IS
 BEGIN
   dbms_output.put_line('欢迎你:'||USER);
   dbms_output.put_line('现在是:'||to_char(SYSDATE,'yyyy-MM-dd'));
 END proc_1;
 
 --在代码块中对存储过程进行调用
 BEGIN
    proc_1;
 END;
 
 --2.有参存储过程
   --带有输入参数的存储过程
   --1.使用标量变量作为输入参数
   CREATE OR REPLACE PROCEDURE add_dept1(deptno dept.deptno%TYPE,
         dname dept.dname%TYPE,loc dept.loc%TYPE ) IS   
   BEGIN
     INSERT INTO dept VALUES(deptno,dname,loc);  
     COMMIT;
     EXCEPTION 
       WHEN dup_val_on_index THEN
           dbms_output.put_line('主键冲突,请重新设置'); 
   END add_dept1;
   
   --测试
   BEGIN
     --add_dept1(70,'山科大','青岛开发区');
     --add_dept1(deptno=>80,dname=>'青岛大学',loc=>'崂山区');
     add_dept1(&deptno,'&dname','&loc');
   END;
   SELECT * FROM dept;
   
   
   --2.使用记录类型作为输入参数
   CREATE OR REPLACE PROCEDURE add_dept2(dept_record dept%ROWTYPE) IS   
   BEGIN
     INSERT INTO dept VALUES dept_record;
     EXCEPTION 
       WHEN dup_val_on_index THEN
           dbms_output.put_line('主键冲突,请重新设置');
   END add_dept2;
   
   --测试
   DECLARE 
       dept_record dept%ROWTYPE;
   BEGIN
     dept_record.deptno:=&deptno;
     dept_record.dname:='&dname';
     dept_record.loc:='&loc';
     
     add_dept2(dept_record);
   END;  
   
   
   --3.使用集合类型作为输入参数
   
   CREATE TYPE deptno_table_type IS TABLE OF NUMBER(2);
   CREATE TYPE dname_table_type IS TABLE OF VARCHAR2(14);
   CREATE TYPE loc_table_type IS TABLE OF VARCHAR2(13);
   CREATE TYPE  p_emphiredate IS TABLE OF VARCHAR2(13);
  -- CREATE TABLE department AS
          SELECT * FROM dept;
   
   --三个数据集合作为参数
   CREATE OR REPLACE PROCEDURE add_dept3(deptno_table deptno_table_type,dname_table dname_table_type,
           loc_table loc_table_type) IS   
   BEGIN
     FOR i IN 1..deptno_table.count LOOP
        INSERT INTO department VALUES(deptno_table(i),dname_table(i),loc_table(i));
     END LOOP; 
     COMMIT; 
     EXCEPTION 
       WHEN dup_val_on_index THEN
           dbms_output.put_line('主键冲突,请重新设置');
       WHEN SUBSCRIPT_BEYOND_COUNT THEN
           dbms_output.put_line('部分集合的元素数值不够');
   END add_dept3;
   
   --调用测试
   DECLARE
       deptno_table deptno_table_type;
       dname_table dname_table_type;
       loc_table loc_table_type;
   BEGIN
     --BULK COLLECT INTO可以批量查询,提高查询效率,into后面跟的必须是集合
     SELECT * BULK COLLECT INTO deptno_table,dname_table,loc_table FROM dept;
     FOR i IN 1..deptno_table.count LOOP
       deptno_table(i):=deptno_table(i)+2;
     END LOOP;
     add_dept3(deptno_table,dname_table,loc_table);     
   END;
   
   SELECT * FROM department ORDER BY deptno ASC;
   
   
   --带有输出参数的存储过程
   --1.标量变量
   CREATE OR REPLACE PROCEDURE get_dept1(p_deptno dept.deptno%TYPE,
          dname OUT dept.dname%TYPE,loc OUT dept.loc%TYPE) IS
   
   BEGIN
          SELECT dname,loc INTO dname,loc  FROM dept WHERE deptno=p_deptno;
          EXCEPTION 
            WHEN NO_DATA_FOUND THEN
              dbms_output.put_line('该部门不存在');
   END get_dept1;
   
   --调用测试
   DECLARE
       p_deptno dept.deptno%TYPE;
       dname  dept.dname%TYPE;
       loc  dept.loc%TYPE;
   BEGIN
       p_deptno:=&deptno;
       get_dept1(p_deptno,dname,loc);
       dbms_output.put_line('部门号:'||p_deptno);
       dbms_output.put_line('部门名称:'||dname);
       dbms_output.put_line('部门地址:'||loc);
   END;  
   
   
   --2.记录类型
   CREATE OR REPLACE PROCEDURE get_dept2(p_deptno dept.deptno%TYPE, dept_record OUT dept%ROWTYPE) IS
   
   BEGIN 
     SELECT * INTO dept_record  FROM dept WHERE deptno=p_deptno;
     EXCEPTION 
            WHEN NO_DATA_FOUND THEN
              dbms_output.put_line('该部门不存在');
   END get_dept2;
   --调用测试
   DECLARE
       p_deptno dept.deptno%TYPE;
       dept_record dept%ROWTYPE;
   BEGIN
       p_deptno:=&deptno;
       get_dept2(p_deptno,dept_record);
       dbms_output.put_line('部门号:'||dept_record.deptno);
       dbms_output.put_line('部门名称:'||dept_record.dname);
       dbms_output.put_line('部门地址:'||dept_record.loc);
       
   END;
   
   --3.集合类型
   CREATE OR REPLACE PROCEDURE get_dept3(p_loc dept.loc%TYPE,deptno_table OUT deptno_table_type,
          dname_table OUT dname_table_type) IS
   BEGIN
          SELECT deptno,dname BULK COLLECT INTO deptno_table,dname_table FROM dept WHERE lower(loc)=p_loc;
          EXCEPTION 
            WHEN NO_DATA_FOUND THEN
              dbms_output.put_line('该部门不存在');
   END get_dept3;
   
   --调用测试
   DECLARE
       p_loc dept.loc%TYPE;
       deptno_table  deptno_table_type;
       dname_table  dname_table_type;
   BEGIN
      p_loc:=LOWER('&loc');
      get_dept3(p_loc,deptno_table,dname_table);
      
      --使用循环对数据进行处理
      FOR i IN 1..deptno_table.count LOOP
        dbms_output.put_line('部门号:'||deptno_table(i));
        dbms_output.put_line('部门名称:'||dname_table(i));
        dbms_output.put_line('部门地址:'||p_loc);
        dbms_output.put_line('=====================');
      END LOOP;
      
   END;
   
   --带有输入输出参数的存储过程
   --计算2个数的和与差
   CREATE OR REPLACE PROCEDURE add_sub(n1 IN OUT NUMBER,n2 IN OUT NUMBER) IS
   BEGIN
     n1:=n1+n2;
     n2:=n1-2*n2;
   END add_sub;
   
   --调用测试
   DECLARE
       num1 NUMBER:=&num1;
       num2 NUMBER:=&num2;
   BEGIN
       add_sub(num1,num2);
       dbms_output.put_line('和:'||num1);
       dbms_output.put_line('差:'||num2);
   END;
   
   

  ----- 练习部分
  --1. 特殊员工加薪10%后,如果该员工参加工作时间超过5年,额外加薪3000.
  CREATE OR REPLACE PROCEDURE salary_test(p_empno emp.empno%TYPE, p_emphiredate OUT NUMBER) IS   
   BEGIN
    SELECT ceil(months_between(SYSDATE,hiredate)/12) YEAR INTO p_emphiredate  FROM emp WHERE empno=p_empno;
     IF p_emphiredate>5 THEN 
       
       UPDATE emp SET sal=sal*1.1+3000 WHERE empno=p_empno;
       ELSE
         UPDATE emp SET sal=sal*1.1 WHERE empno=p_empno;
       END IF;
     COMMIT;
   END salary_test;
   --测试
  DECLARE
        p_empno emp.empno%TYPE:=&empno;
        p_emphiredate NUMBER;
   BEGIN 
    salary_test(p_empno,p_emphiredate);
   END;
   
  SELECT * FROM emp;
  
  --2. 检查员工工资是否在有效的范围内,不同工作的工资范围为:
  --CLERK      1500-2500
  --SALES      2501-3500
  --ANALYST    3501-4500
  --MANAGER    4500以上
  --如果工资在此范围内,输出工资正常,否则输出工资太低,并且更新工资为该范围内的最低工资 


   CREATE OR REPLACE PROCEDURE test_2(p_empno emp.empno%TYPE, p_empjob OUT emp.job%TYPE,p_empsalary OUT  NUMBER) IS   
   BEGIN
    SELECT sal INTO p_empsalary  FROM emp WHERE empno=p_empno;
    SELECT job INTO p_empjob FROM emp WHERE empno=p_empno;
     IF p_empjob='CLERK' THEN 
       IF p_empsalary>1500 AND p_empsalary<2500 THEN
         dbms_output.put_line('工资正好');
       ELSE
         dbms_output.put_line('工资太低');
         UPDATE  emp SET sal=1500; 
      END IF;
      ELSIF p_empjob='SALESMAN' THEN 
      IF p_empsalary>2501 AND p_empsalary<3500 THEN 
        dbms_output.put_line('工资正好');
        ELSE 
        dbms_output.put_line('工资太低');
        END IF;
       END IF;
     COMMIT;
   END test_2;
    -----------测试
  DECLARE
      
        p_empno emp.empno%TYPE:=&empno;
        p_empjob emp.job%TYPE;
        p_empsalary NUMBER;
   BEGIN 
    test_2(p_empno,p_empjob,p_empsalary);
   END;
   
   
   /*
   4.汇总每个部门每个职位员工的最高及平均工资,包括显示部门名称
和职位名称,将数据存储到Test表中,并将工资最高的部门和职位,以及最高工资用OUT参数输出。要求使用存储过程

   */
   
   
   
   
   
   
   
   
   
   
   
    SELECT * FROM copy_emp

   
   
   
   



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值