`
laonao
  • 浏览: 5235 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

自定义记录类型游标

阅读更多
CREATE OR REPLACE PROCEDURE pr_attendleave(year     in varchar2,
                                           statdate IN date,
                                           empId    in varchar2) AS
BEGIN
  DECLARE
    司龄             number(10, 2);
    工龄             number(10, 2);
    核定年休假天数   number(10, 2);
    num4             number(10);
    核定年度最后一天 Date;
    核定年度第一天   Date;
    核定年度剩余天数 number(10);
    upyearDay        number(10, 2); --上一年剩余年假天数
    type ref_c_type is ref cursor; --定义游标
    type rec_aaa is record(
      empid          gcemployee.empid%type,
      joindate       gcemployee.joindate%type,
      startworkdate  gcemployee.startworkdate%type,
      MonthDeduction gcemployee.MonthDeduction%type); 
    empIdResult ref_c_type; --实例化这个游标类型 
    aaa         rec_aaa;
    ref_c_sql   varchar2(500); --动态游标的sql
  BEGIN
    ref_c_sql := 'select empid,joindate,startworkdate,MonthDeduction from gcemployee t where t.status=''ES1''';
    if (empId is not null) or empId <> '' then
      ref_c_sql := ref_c_sql || ' and t.empid=''' || empId || '''';
    end if;
    open empIdResult for ref_c_sql;
    LOOP
      fetch empIdResult into aaa;
      exit when empIdResult%notfound;
      司龄 := months_between(statdate, aaa.joindate); --司龄
      工龄 := months_between(statdate, aaa.startworkdate) -
            nvl(aaa.MonthDeduction, 0); --工龄
      if (year = '2008') then
        if (司龄 > 24) then
          --进本单位大于2年的 考虑工作日期
          if (工龄 > 21 * 12) then
            --判断大于21年的
            核定年休假天数 := 15;
          elsif (工龄 > 20 * 12) then
            --判断大于20 可能出现工龄界点
            核定年休假天数 := 10 * (1 - (工龄 - 240) / 12) + 15 * ((工龄 - 240) / 12);
          elsif (工龄 > 11 * 12) then
            --判断大于11年
            核定年休假天数 := 10;
          elsif (工龄 > 10 * 12) then
            --判断大于10年 可能出现工龄界点
            核定年休假天数 := 5 * (1 - (工龄 - 120) / 12) + 10 * ((工龄 - 120) / 12);
          else
            核定年休假天数 := 5; --判断小于10年的为5天
          end if;
        elsif (司龄 between 12 and 24) then
          --不到2年的 需要计算 百分比
          if (工龄 > 21 * 12) then
            --判断大于21年的
            核定年休假天数 := 15;
          elsif (工龄 > 20 * 12) then
            --判断大于20
            核定年休假天数 := 10 * (1 - (工龄 - 240) / 12) + 15 * ((工龄 - 240) / 12);
          elsif (工龄 > 11 * 12) then
            --判断大于11年
            核定年休假天数 := 10;
          elsif (工龄 > 10 * 12) then
            核定年休假天数 := 5 * (1 - (工龄 - 120) / 12) + 10 * ((工龄 - 120) / 12);
          else
            核定年休假天数 := 5; --判断小于10年的为5天
          end if;
        else
          --不到1年的均为0
          核定年休假天数 := 0;
        end if;
      else
        --大于2008年的
        if (司龄 > 24) then
          --进本单位大于2年的 考虑工作日期
          if (工龄 > 21 * 12) then
            --判断大于21年的
            核定年休假天数 := 15;
          elsif (工龄 > 20 * 12) then
            --判断大于20 可能出现工龄界点
            核定年休假天数 := 10 * (1 - (工龄 - 240) / 12) + 15 * ((工龄 - 240) / 12);
          elsif (工龄 > 11 * 12) then
            --判断大于11年
            核定年休假天数 := 10;
          elsif (工龄 > 10 * 12) then
            --判断大于10年 可能出现工龄界点
            核定年休假天数 := 5 * (1 - (工龄 - 120) / 12) + 10 * ((工龄 - 120) / 12);
          else
            核定年休假天数 := 5; --判断小于10年的为5天
          end if;
        elsif (司龄 between 12 and 24) then
          --不到2年的 需要计算 百分比
          if (工龄 > 21 * 12) then
            --判断大于21年的
            核定年休假天数 := 15;
          elsif (工龄 > 20 * 12) then
            --判断大于20
            核定年休假天数 := 10 * (1 - (工龄 - 240) / 12) + 15 * ((工龄 - 240) / 12);
          elsif (工龄 > 11 * 12) then
            --判断大于11年
            核定年休假天数 := 10;
          elsif (工龄 > 10 * 12) then
            核定年休假天数 := 5 * (1 - (工龄 - 120) / 12) + 10 * ((工龄 - 120) / 12);
          elsif (工龄 > 24) then
            核定年休假天数 := 5; --判断小于10年的为5天
          elsif (工龄 > 12) then
            核定年休假天数 := 5 * (工龄 - 12) / 12; --判断小于10年的为5天
          else
            核定年休假天数 := 0;
          end if;
        else
          --近公司不足一年的
          if (工龄 > 21 * 12) then
            --判断大于21年的 司龄界点
            核定年休假天数 := 15 * (司龄) / 12;
          elsif (工龄 > 20 * 12) then
            --判断大于20  可能出现工龄、司龄界点
            --判断先出现 工龄界点还是司龄界点
            if ((工龄 - 240) > (司龄)) then
              --工龄月份早 如工龄 3月 司龄 5月
              核定年休假天数 := 15 * ((司龄) / 12);
            elsif ((司龄) < (工龄 - 240)) then
              --工龄月份早 如司龄 5月 工龄 7月
              核定年休假天数 := 10 * ((工龄 - 240 + 司龄) / 12) + 15 * (工龄 - 240) / 12;
            end if;
          elsif (工龄 > 11 * 12) then
            --判断大于11年
            核定年休假天数 := 10;
          elsif (工龄 > 10 * 12) then
            --判断大于10年 可能出现工龄、司龄界点
            --判断先出现 工龄界点还是司龄界点
            if ((工龄 - 120) > (司龄)) then
              --工龄月份早 如工龄 3月 司龄 5月
              核定年休假天数 := 10 * ((司龄) / 12);
            elsif ((司龄) < (工龄 - 120)) then
              --工龄月份早 如司龄 5月 工龄 7月
              核定年休假天数 := 5 * ((工龄 - 120 + 司龄) / 12) + 10 * (工龄 - 120) / 12;
            end if;
          elsif (工龄 > 24) then
            核定年休假天数 := 5; --判断小于10年的为5天
          elsif (工龄 > 12) then
            --核定年休假天数:=5 * (1-(工龄 -12)/12);   --判断小于10年的为5天
            if ((工龄 - 12) >= (司龄)) then
              --工龄月份早 如工龄 3月 司龄 5月
              核定年休假天数 := 5 * ((司龄) / 12);
            else
              --工龄月份早 如司龄 5月 工龄 7月
              核定年休假天数 := 5 * (工龄 - 12) / 12;
            end if;
          else
            核定年休假天数 := 0;
          end if;
        end if;
      end if;
      -- 统计当年最后一天
      核定年度最后一天 := to_date(year || '1231', 'yyyyMMdd');
      核定年度第一天   := to_date(year || '0101', 'yyyyMMdd');
      -- 如果是统计当年入司,计算剩余日历
      if (aaa.joindate <= 核定年度最后一天 and 核定年度第一天 <= aaa.joindate) then
        -- 剩余天数
        核定年度剩余天数 := trunc((((86400 * (核定年度最后一天 - aaa.joindate)) / 60) / 60) / 24);
        核定年休假天数   := trunc(核定年休假天数 * 核定年度剩余天数 / 365);
      end if;
    
      select count(*) into num4 from GCAttendLeave where StatYear = year and EmpID = aaa.empid;
      if (num4 > 0) then
        Update GCAttendLeave Set AnnualLeaveI = trunc(核定年休假天数), ynxjleavei   = nvl(upyearDay, 0.0) where EmpID = aaa.empid and StatYear = year;
      else
        INSERT INTO GCAttendLeave(EmpID, StatYear, AnnualLeaveI, ynxjleavei) VALUES(aaa.empid, year, trunc(核定年休假天数), nvl(upyearDay, 0.0));
      end if;
    END Loop;
    close empIdResult;
  END;
end;

 

分享到:
评论

相关推荐

    Oracle游标视图和自定义函数

    ### Oracle游标、视图和自定义函数 #### 1. 游标 **1.1 游标的优势和类型** 在数据库应用开发过程中,游标作为一种强大的工具,为开发者提供了一种处理从表中检索出的数据的有效方法,特别是在需要逐条处理数据...

    oracle-游标使用汇总.doc

    这里的`variable`是与游标查询结果列相匹配的变量,它们的数据类型应与查询结果列的类型一致。例如: ```sql FETCH C_EMP INTO v_ename, v_salary; ``` 如果有多行结果,可以使用循环结构配合游标的状态属性`%NOT...

    Oracle显式游标和隐式游标.doc

    在 PL/SQL 中,记录是一种用户自定义的数据类型,可以把记录看作是一个变量,保存在内存空间中,在使用记录时候,要首先定义记录结构,然后声明记录变量。 在使用游标时,还需要注意游标的四种属性:SQL %ISOPEN、...

    Oracle_PLSQL游标的学习

    Oracle PL/SQL 游标的学习 游标是 Oracle PL/SQL 中的一个重要...* 可以把 PL/SQL 记录看作是一个用户自定义的数据类型。 在 PL/SQL 中使用游标可以提高程序的效率和可读性,同时也可以使得代码更加简洁和易于维护。

    游标与异常处理代码

    - `%ROWCOUNT`:返回从游标中已读取的记录数 2. **带参数的游标** 游标可以接受参数,以便根据输入值动态地改变查询。例如,输出指定部门的员工信息,我们可以定义一个带参数的游标: ```sql CURSOR c_employee...

    Oracle游标使用方法及语法大全

    - `%ROWTYPE`关键字允许我们创建与查询结果列匹配的记录类型。 3. **游标FOR循环**: - 这种类型的游标简化了代码,不需要显式打开、关闭和提取。示例: ```sql FOR r1 IN (SELECT empno, salary FROM emp ...

    利用游标返回结果集的的例子(Oracle 存储过程).doc

    1. 定义一个程序包来创建自定义游标类型。 2. 创建一个函数,通过游标返回查询结果。 3. 创建一个过程,接收一个游标参数并填充结果集。 4. 使用Java的JDBC API调用这些存储过程,处理返回的游标结果。 这种技术在...

    ORACLE 游标 异常 存储过程

    - **类型**:有两种主要类型的游标——隐式游标和显式游标。隐式游标由SQL语句(如SELECT INTO)自动管理,而显式游标则需要程序员手动声明、打开、读取、关闭等。 - **使用**:在PL/SQL中,通过声明、打开、提取...

    oracle函数触发器游标等几个小例子

    在`v_ceshiFunction.sql`和`v_ceshiFunction(表名当参数).sql`中,可能包含了自定义函数的创建和使用示例。函数可以接受参数,执行特定操作,然后返回结果。例如,你可以创建一个计算平均值的函数,或者一个检查输入...

    游标 存储过程游标 存储过程.doc

    打开游标执行SELECT查询,并将游标指针定位到第一条记录。`FETCH`命令用于获取游标当前指向的记录,并可选择不同的导航选项(如`NEXT`、`PRIOR`、`FIRST`、`LAST`等)。关闭游标`CLOSE`和释放游标`DEALLOCATE`分别...

    Qcustormplot 实现鼠标框选 放大缩小 拖拽 游标显示及吸附

    QCustomPlot是一个自定义的QGraphicsView子类,它可以绘制各种类型的图表,如折线图、散点图、柱状图等。其设计目标是提供灵活且高效的图形接口,以便开发者能够方便地进行数据可视化。 实现鼠标框选功能,我们通常...

    存储过程和游标详解

    游标是数据库中的另一种重要特性,主要用于处理结果集中的多行记录,允许逐行访问和修改数据。 ##### 游标的概念和优势: 游标允许开发者以类似循环的方式处理查询结果集中的每一行数据,这对于需要逐条处理数据的...

    Sqlserver 自定义函数 Function使用介绍

    通过自定义函数和游标,SQL Server用户可以更灵活地处理和操纵数据库中的数据,提高代码复用性和查询效率。在实际开发中,根据需求选择合适类型的函数,可以极大地优化数据库性能和程序的可维护性。

    oracle 的函数、存储过程、游标、简单实例

    在Oracle中,游标有两种类型:隐式游标(由SELECT语句自动管理)和显式游标(由开发者手动控制)。使用游标,你可以逐行处理数据,更新、插入或删除记录,而无需一次性加载所有结果。 现在,我们来看一些**简单实例...

    oracle循环游标

    例如,当尝试更新不存在的记录时,可以引发自定义异常或使用预定义的`sql%notfound`条件。这有助于开发者更好地控制程序流程,确保在遇到错误时能够采取适当的措施,如输出错误信息或执行回滚操作。 另外,代码还...

    oracle游标使用大全.doc

    这里,`cursor_name`是你自定义的游标名称,`select_statement`是你的SQL查询语句。例如: ```sql DECLARE CURSOR C_EMP IS SELECT empno, ename, salary FROM emp WHERE salary &gt; 2000 ORDER BY ename; ``` ...

    游标参数的存储过程 存储过程高级教程

    1. 声明游标:定义游标的类型,通常基于一个SQL查询。 2. 打开游标:执行查询并创建一个指向结果集的指针。 3. 循环处理:通过提取游标(FETCH)获取当前行数据,进行相应的操作。 4. 关闭游标:处理完所有行后,...

    Oracle存储过程返回游标实例详解

    这种方法中,自定义游标类型`type_cursor`和记录类型`type_record`都在包中定义。这使得游标具有更强的类型约束,但同时也限制了其在包外的使用。 总结来说,Oracle存储过程返回游标是处理大量数据的有效途径。通过...

    强大的自定义标签分页,内有说明

    在自定义标签分页的场景中,反射可能用于在运行时动态获取和设置分页相关的属性,比如每页显示的记录数、当前页码等,增强了代码的灵活性。 最后,"rs游标"指的是ResultSet游标,这是Java数据库连接(JDBC)中的一...

    Ibatis调用Oracle存储过程返回自定义类型

    这个存储过程通过游标遍历查询结果,并将其封装到`WEALTH_DEAL_DETAIL_ARRAY`类型中。 #### 使用Ibatis调用存储过程 Ibatis是一个Java持久层框架,它能够简化Java应用程序与数据库之间的交互。为了调用上述存储...

Global site tag (gtag.js) - Google Analytics