0

我怎样才能减少程序的时间?现在需要 7 分钟才能完成,我在报告中使用 Cursor for 循环在一个月内围绕 400 名员工(使用 Cursor for 循环)循环 30 天(使用 While 循环循环日期),包括缺勤或当前计算,现在我想减少完成报告的时间输出我的 oracle 版本是 11g R2,操作系统是 Windows 7 或 Windows 2008 服务器。

create or replace PROCEDURE SP_SAPABSENTRPT
( 
  "P_FROMDATE" IN DATE,  "P_TODATE" IN DATE,  "GRADE" IN NUMBER,  "EMPID" IN NUMBER,  "DEPTID" IN NUMBER,  CUR_OUT OUT SYS_REFCURSOR
)
AS

EMPIDCNT NUMBER; EMPNO VARCHAR2(100); NOOFDAYS NUMBER:=0;DAYS NUMBER;V_CNTEMPSYSIDFN NUMBER;V_EMPID NUMBER;
V_LOOP  NUMBER := 1;CNTSYSID NUMBER;V_DATEOFAB VARCHAR2(30);V_CNTEMPSYSID NUMBER;V_CNTEMPSYSIDAN NUMBER; V_COUNT NUMBER;
FROM_DATE DATE;V_FIRSTHALFPRESENT NUMBER;V_SECONDHALFPRESENT NUMBER;V_CNT NUMBER;V_FULLDAYPRESENT NUMBER;V_PRVSDAYCNT NUMBER;
V_STARTTIME VARCHAR2(20);V_ENDTIME VARCHAR2(20);V_BREAKOUT VARCHAR2(20);V_BREAKIN VARCHAR2(20);V_EARTLYTIME VARCHAR2(20);V_LEAVETYPE VARCHAR2(20);
V_EARLTYCNT NUMBER;V_PRESENTEMPCNT NUMBER;V_EMPNO NUMBER;V_FULLDAYLEAVE NUMBER;V_FULLDAYOOD NUMBER;V_LEAVECNT NUMBER;V_OODCNT NUMBER;
V_FHLVSHPRESENT NUMBER;V_SHLVFHPRESENT NUMBER;V_FIRSTHALFOOD NUMBER;V_SECONDHALFOOD NUMBER;V_FHLVSHOOD NUMBER;V_SHLVFHOOD NUMBER;
V_FHOODSHLV NUMBER;V_SHOODFHLV NUMBER;V_FHLVSHABSENT NUMBER;V_FHOODSHABSENT NUMBER;V_SHLVFHABSENT NUMBER;V_SHOODFHABSENT NUMBER;V_TBLCNT NUMBER;
V_STWEEKDAY VARCHAR2(10);V_HOLIDAYCNT NUMBER;V_GRADECODE VARCHAR2(20);V_SHIFTCNT NUMBER;V_STALLTENDATE DATE;V_SUNDAYCNT NUMBER;
V_NXTDAYFULL_LVCNT NUMBER;V_NXTDAYSN_LVCNT NUMBER;V_NEXTDAY_SCHLABS NUMBER;V_STARTTIME1 VARCHAR2(20);V_BREAKOUT1 VARCHAR2(20);
V_FIRSTHALFPRESENT1 NUMBER;V_FLDAYHLDAY VARCHAR2(6);V_NEXTDAY_FSHLABS NUMBER;V_NEXTDAY_FULLABS NUMBER;V_NXTDAYFULL_OODCNT NUMBER;

CURSOR C_EMPID IS

SELECT E.SYSID FROM EMPLOYEE E,GRADE G,DEPARTMENT D
WHERE E.GRADE_SYSID=G.SYSID AND G.SYSID=DECODE(SP_SAPABSENTRPT.GRADE ,0,G.SYSID,SP_SAPABSENTRPT.GRADE)
AND E.DEPARTMENT_SYSID=D.SYSID AND  D.SYSID= DECODE(SP_SAPABSENTRPT.DEPTID ,0,D.SYSID,SP_SAPABSENTRPT.DEPTID )
AND E.SYSID=DECODE(SP_SAPABSENTRPT.EMPID,0,E.SYSID,SP_SAPABSENTRPT.EMPID) AND E.GRADE_SYSID NOT IN (325,326) ORDER BY E.SYSID;
--The Grades E8 and E9 not included in this report as per Rakesh (BHEL Employee) email on May 30 2013 2:06 PM  

begin

    DELETE FROM TEMPSAP_EMPLOGABSENT;
  --DELETE FROM TMPEMPIDS;
  COMMIT;
  DBMS_OUTPUT.PUT_LINE(TO_CHAR(SYSDATE,'DD-MON-YY HH24:MI:SS'));
  OPEN C_EMPID;
  LOOP
    FETCH C_EMPID INTO V_EMPID;
    EXIT WHEN C_EMPID%NOTFOUND;

      --for r_rec in c_rec loop
      FROM_DATE:=TRIM(P_FROMDATE);

        WHILE NOT TO_DATE(FROM_DATE,'DD-MM-YYYY') > TO_DATE(P_TODATE,'DD-MM-YYYY')
           LOOP --Looping the dates from given start and end date

      --********************************************************************************************************************
       SELECT EMPNO INTO V_EMPNO FROM EMPLOYEE WHERE SYSID=V_EMPID;

              SELECT G.CODE INTO V_GRADECODE FROM GRADE G,EMPLOYEE E
              WHERE E.GRADE_SYSID=G.SYSID AND E.SYSID=V_EMPID;              


           --Getting shift timings from Shiftallotment table if shift not available else will go for EG General Shift 
            SELECT COUNT(SYSID) INTO V_SHIFTCNT FROM SHIFTSALLOTMENT
            WHERE TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY') AND EMPNO=V_EMPNO;

           IF(V_SHIFTCNT=0) THEN --IF no shift allotted for the date alloing EG shift

              SELECT last_day(add_months(sysdate,12 - to_number(to_char(sysdate,'mm')))) INTO V_STALLTENDATE from dual;

              INORUP_SHIFTSALLOTMENT_PROC(0,0,V_EMPID,201,FROM_DATE,V_STALLTENDATE,101);

           END IF;

          IF(V_SHIFTCNT!=0) THEN --Shift IF Open

             SELECT TO_CHAR(TO_DATE(FROM_DATE,'DD-MM-YY'),'DY') INTO V_STWEEKDAY FROM DUAL;

             IF(V_STWEEKDAY!='SAT') THEN --Validating the week is not sunday get the results from the starting week from previous month.

                SELECT S.STARTTIME,S.ENDTIME,S.BREAKOUT,S.BREAKIN INTO V_STARTTIME,V_ENDTIME,V_BREAKOUT,V_BREAKIN
                FROM SHIFTS S,SHIFTSALLOTMENT SA WHERE S.SYSID=SA.SHIFTID AND SA.EMPNO=V_EMPNO
                AND TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY');

             ELSE

                SELECT S.SATURDAYSTART INTO V_STARTTIME
                FROM SHIFTS S,SHIFTSALLOTMENT SA WHERE S.SYSID=SA.SHIFTID AND SA.EMPNO=V_EMPNO 
                AND TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY');

               IF(V_STARTTIME IS NOT NULL) THEN --IF no shift on saturday then select weekday shift only

                  SELECT S.SATURDAYSTART,S.SATURDAYEND,S.SATURDAYLUNCHSTART,S.SATURDAYLUNCHEND
                  INTO V_STARTTIME,V_ENDTIME,V_BREAKOUT,V_BREAKIN FROM SHIFTS S,SHIFTSALLOTMENT SA 
                  WHERE S.SYSID=SA.SHIFTID AND SA.EMPNO=V_EMPNO AND TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY');

               ELSE

                  SELECT S.STARTTIME,S.ENDTIME,S.BREAKOUT,S.BREAKIN INTO V_STARTTIME,V_ENDTIME,V_BREAKOUT,V_BREAKIN
                  FROM SHIFTS S,SHIFTSALLOTMENT SA WHERE S.SYSID=SA.SHIFTID AND SA.EMPNO=V_EMPNO
                  AND TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY');               

               END IF;

             END IF;          
          END IF; --End Shift IF


              IF(V_GRADECODE LIKE 'E%' OR V_GRADECODE LIKE 'S%' OR V_GRADECODE='FTA') THEN

                  V_STARTTIME:=ADDHOURS_FUN(TO_CHAR(TO_DATE(V_STARTTIME,'HH:MI PM'),'HH24:MI'),TO_CHAR(TO_DATE('00:30','HH24:MI'),'HH24:MI'));
              ELSE
                  V_STARTTIME:=ADDHOURS_FUN(TO_CHAR(TO_DATE(V_STARTTIME,'HH:MI PM'),'HH24:MI'),TO_CHAR(TO_DATE('01:00','HH24:MI'),'HH24:MI'));
              END IF;

              V_EARTLYTIME:=HOURSDIFFERENCEFUN_FUN(to_char(to_date(V_ENDTIME,'HH:MI PM'),'HH24:MI'),TO_CHAR(TO_DATE('02:00','HH24:MI'),'HH24:MI'));              


              SELECT COUNT(L.SYSID) INTO V_LEAVECNT FROM LEAVEFORMENTRY L WHERE L.EMPNO=V_EMPNO 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.ACTIVE='1';

              SELECT COUNT(L.SYSID) INTO V_CNT FROM LEAVETYPE LT,LEAVEFORMENTRY L
              WHERE LT.SYSID=L.LEAVETYPE AND L.EMPNO=V_EMPNO
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.ACTIVE='1';

              IF(V_CNT!=0) THEN

                  SELECT LT.LEAVETYPE INTO V_LEAVETYPE FROM LEAVETYPE LT,LEAVEFORMENTRY L
                  WHERE LT.SYSID=L.LEAVETYPE AND L.EMPNO=V_EMPNO 
                  AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
                  AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.ACTIVE='1';

              END IF;

              SELECT COUNT(O.SYSID) INTO V_OODCNT FROM OODENTRY O WHERE O.EMPID=V_EMPID 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(O.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND O.ACTIVE=1 ; 

              --First halfs
              SELECT COUNT(SYSID) INTO V_FIRSTHALFPRESENT FROM ATTENDENCELOG
              WHERE TO_DATE(DATERECORDED,'DD-MM-YYYY')=TO_DATE(FROM_DATE,'DD-MM-YYYY') AND EMPLOYEE_SYSID=V_EMPID
              AND TO_CHAR(TO_DATE(INTIME, 'HH24:MI:SS'),'HH24:MI') <= TO_CHAR(TO_DATE(V_STARTTIME, 'HH:MI PM'),'HH24:MI')
              AND  to_char(to_date(OUTTIME, 'HH24:MI:SS'),'HH24:MI')  >= to_char(to_date(V_BREAKOUT, 'HH:MI PM'),'HH24:MI')
              AND V_EMPID NOT IN(
              SELECT (E1.SYSID) FROM LEAVEFORMENTRY L,EMPLOYEE E1 WHERE L.EMPNO=E1.EMPNO 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.EMPNO=V_EMPNO AND L.ACTIVE='1' AND L.FNTYPE='FN')
              AND V_EMPID NOT IN(SELECT E2.SYSID FROM OODENTRY O, EMPLOYEE E2 WHERE O.EMPID=E2.SYSID 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(O.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE,'MM-DD-YYYY'),'DD-MON-YY') AND O.EMPID=V_EMPID AND O.ACTIVE=1 AND O.DAYTYPE='FN');              

              --Second Halfs
              SELECT COUNT(SYSID) INTO V_SECONDHALFPRESENT FROM ATTENDENCELOG
              WHERE TO_DATE(DATERECORDED,'DD-MM-YYYY')=TO_DATE(FROM_DATE,'DD-MM-YYYY') AND EMPLOYEE_SYSID=V_EMPID
              AND (to_char(to_date(INTIME, 'HH24:MI:SS'),'HH24:MI') <= to_char(to_date(V_BREAKIN, 'HH:MI PM'),'HH24:MI') 
              OR to_char(to_date(INTIME, 'HH24:MI:SS'),'HH24:MI') >= to_char(to_date(V_BREAKIN, 'HH:MI PM'),'HH24:MI'))
              AND  to_char(to_date(OUTTIME, 'HH24:MI:SS'),'HH24:MI')  >= to_char(to_date(V_ENDTIME, 'HH:MI PM'),'HH24:MI')
              AND V_EMPID NOT IN(
              SELECT (E1.SYSID) FROM LEAVEFORMENTRY L,EMPLOYEE E1 WHERE L.EMPNO=E1.EMPNO 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.EMPNO=V_EMPNO AND L.ACTIVE='1' AND L.FNTYPE='AN')
              AND V_EMPID NOT IN(SELECT E2.SYSID FROM OODENTRY O, EMPLOYEE E2 WHERE O.EMPID=E2.SYSID 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(O.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE,'MM-DD-YYYY'),'DD-MON-YY') AND O.EMPID=V_EMPID AND O.ACTIVE=1 AND O.DAYTYPE='AN');

        --********************************************************************************************************************             
              SELECT COUNT(*) INTO V_PRVSDAYCNT FROM TEMPSAP_EMPLOGABSENT WHERE EMPID=V_EMPID AND FROM_DATE-1 BETWEEN ABSENTFROM AND ABSENTTO;
              SELECT COUNT(SYSID) INTO V_HOLIDAYCNT FROM HOLIDAY WHERE TO_DATE(HOLIDAYDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MON-YY');              
              SELECT COUNT(*) INTO V_SUNDAYCNT FROM DUAL WHERE TO_CHAR(TO_DATE(FROM_DATE,'DD-MM-YY'),'DY')='SUN';

              SELECT COUNT(L.SYSID) INTO V_NXTDAYFULL_LVCNT FROM LEAVEFORMENTRY L,EMPLOYEE E1 WHERE L.EMPNO=E1.EMPNO AND L.ACTIVE='1'
              AND TO_DATE(FROM_DATE,'DD-MON-YY')+1 BETWEEN TO_CHAR(TO_DATE(L.FROMDATE,'MM-DD-YYYY'),'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE,'MM-DD-YYYY'),'DD-MON-YY') AND L.FNTYPE='FULL' AND L.EMPNO=V_EMPNO;

              SELECT COUNT(E1.SYSID) INTO V_NXTDAYFULL_OODCNT FROM OODENTRY O,EMPLOYEE E1 WHERE O.EMPID=E1.SYSID AND O.ACTIVE='1'
              AND TO_DATE(FROM_DATE,'DD-MON-YY')+1 BETWEEN TO_CHAR(TO_DATE(O.FROMDATE,'MM/DD/YYYY'),'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE,'MM/DD/YYYY'),'DD-MON-YY') AND O.DAYTYPE='FULL' AND O.EMPID=V_EMPID;

            SELECT COUNT(SYSID) INTO V_SHIFTCNT FROM SHIFTSALLOTMENT
            WHERE TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY')+1 AND EMPNO=V_EMPNO;

            IF(V_SHIFTCNT!=0) THEN --Shift IF Open

             SELECT TO_CHAR(TO_DATE(FROM_DATE,'DD-MM-YY')+1,'DY') INTO V_STWEEKDAY FROM DUAL;

             IF(V_STWEEKDAY!='SAT') THEN --Validating the week is not sunday get the results from the starting week from previous month.

                SELECT S.STARTTIME,S.BREAKOUT INTO V_STARTTIME1,V_BREAKOUT1
                FROM SHIFTS S,SHIFTSALLOTMENT SA WHERE S.SYSID=SA.SHIFTID AND SA.EMPNO=V_EMPNO
                AND TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY')+1;

             ELSE

                SELECT S.SATURDAYSTART INTO V_STARTTIME1
                FROM SHIFTS S,SHIFTSALLOTMENT SA WHERE S.SYSID=SA.SHIFTID AND SA.EMPNO=V_EMPNO 
                AND TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY')+1;

               IF(V_STARTTIME IS NOT NULL) THEN --IF no shift on saturday then select weekday shift only

                  SELECT S.SATURDAYSTART,S.SATURDAYLUNCHSTART
                  INTO V_STARTTIME1,V_BREAKOUT1 FROM SHIFTS S,SHIFTSALLOTMENT SA 
                  WHERE S.SYSID=SA.SHIFTID AND SA.EMPNO=V_EMPNO AND TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY')+1;

               ELSE

                  SELECT S.STARTTIME,S.BREAKOUT INTO V_STARTTIME1,V_BREAKOUT1
                  FROM SHIFTS S,SHIFTSALLOTMENT SA WHERE S.SYSID=SA.SHIFTID AND SA.EMPNO=V_EMPNO
                  AND TO_DATE(SHIFTDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MM-YY')+1;

               END IF;

             END IF;          
          END IF; --End Shift IF


              IF(V_GRADECODE LIKE 'E%' OR V_GRADECODE LIKE 'S%' OR V_GRADECODE='FTA') THEN

                  V_STARTTIME1:=ADDHOURS_FUN(TO_CHAR(TO_DATE(V_STARTTIME1,'HH:MI PM'),'HH24:MI'),TO_CHAR(TO_DATE('00:30','HH24:MI'),'HH24:MI'));
              ELSE
                  V_STARTTIME1:=ADDHOURS_FUN(TO_CHAR(TO_DATE(V_STARTTIME1,'HH:MI PM'),'HH24:MI'),TO_CHAR(TO_DATE('01:00','HH24:MI'),'HH24:MI'));
              END IF;


              SELECT COUNT(SYSID) INTO V_NEXTDAY_SCHLABS FROM ATTENDENCELOG
              WHERE TO_DATE(DATERECORDED,'DD-MM-YYYY')=TO_DATE(FROM_DATE,'DD-MM-YYYY')+1 AND EMPLOYEE_SYSID=V_EMPID
              AND TO_CHAR(TO_DATE(INTIME, 'HH24:MI:SS'),'HH24:MI') <= TO_CHAR(TO_DATE(V_STARTTIME1, 'HH:MI PM'),'HH24:MI')
              AND  TO_CHAR(TO_DATE(OUTTIME, 'HH24:MI:SS'),'HH24:MI')  >= TO_CHAR(TO_DATE(V_BREAKOUT1, 'HH:MI PM'),'HH24:MI')
              AND V_EMPID NOT IN(
              SELECT (E1.SYSID) FROM LEAVEFORMENTRY L,EMPLOYEE E1 WHERE L.EMPNO=E1.EMPNO 
              AND TO_DATE(FROM_DATE,'DD-MM-YY')+1 BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.EMPNO=V_EMPNO AND L.ACTIVE='1' AND L.FNTYPE='FN')
              AND V_EMPID NOT IN(SELECT E2.SYSID FROM OODENTRY O, EMPLOYEE E2 WHERE O.EMPID=E2.SYSID 
              AND TO_DATE(FROM_DATE,'DD-MM-YY')+1 BETWEEN TO_CHAR(TO_DATE(O.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE,'MM-DD-YYYY'),'DD-MON-YY') AND O.EMPID=V_EMPID AND O.ACTIVE=1 AND O.DAYTYPE='FN');

              SELECT COUNT(E.SYSID) INTO V_NEXTDAY_FULLABS FROM EMPLOYEE E
              WHERE V_EMPID NOT IN (SELECT EMPLOYEE_SYSID FROM ATTENDENCELOG
              WHERE TO_DATE(DATERECORDED,'DD-MM-YYYY')=TO_DATE(FROM_DATE,'DD-MM-YYYY')+1 AND EMPLOYEE_SYSID=V_EMPID)
              AND V_EMPID NOT IN(
              SELECT (E1.SYSID) FROM LEAVEFORMENTRY L,EMPLOYEE E1 WHERE L.EMPNO=E1.EMPNO 
              AND TO_DATE(FROM_DATE,'DD-MM-YY')+1 BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.EMPNO=V_EMPNO AND L.ACTIVE='1')
              AND V_EMPID NOT IN(SELECT E2.SYSID FROM OODENTRY O, EMPLOYEE E2 WHERE O.EMPID=E2.SYSID 
              AND TO_DATE(FROM_DATE,'DD-MM-YY')+1 BETWEEN TO_CHAR(TO_DATE(O.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE,'MM-DD-YYYY'),'DD-MON-YY') AND O.EMPID=V_EMPID AND O.ACTIVE=1);

              SELECT COUNT(SYSID) INTO V_NEXTDAY_FSHLABS FROM ATTENDENCELOG
              WHERE TO_DATE(DATERECORDED,'DD-MM-YYYY')=TO_DATE(FROM_DATE,'DD-MM-YYYY') AND EMPLOYEE_SYSID=V_EMPID
              AND (to_char(to_date(INTIME, 'HH24:MI:SS'),'HH24:MI') <= to_char(to_date(V_BREAKIN, 'HH:MI PM'),'HH24:MI') 
              OR to_char(to_date(INTIME, 'HH24:MI:SS'),'HH24:MI') >= to_char(to_date(V_BREAKIN, 'HH:MI PM'),'HH24:MI'))
              AND  to_char(to_date(OUTTIME, 'HH24:MI:SS'),'HH24:MI')  >= to_char(to_date(V_ENDTIME, 'HH:MI PM'),'HH24:MI')
              AND V_EMPID NOT IN(
              SELECT (E1.SYSID) FROM LEAVEFORMENTRY L,EMPLOYEE E1 WHERE L.EMPNO=E1.EMPNO 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.EMPNO=V_EMPNO AND L.ACTIVE='1' AND L.FNTYPE='AN')
              AND V_EMPID NOT IN(SELECT E2.SYSID FROM OODENTRY O, EMPLOYEE E2 WHERE O.EMPID=E2.SYSID 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(O.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE,'MM-DD-YYYY'),'DD-MON-YY') AND O.EMPID=V_EMPID AND O.ACTIVE=1 AND O.DAYTYPE='AN');

          IF(V_PRVSDAYCNT!=0 AND (V_HOLIDAYCNT!=0 OR V_SUNDAYCNT!=0) AND (V_NEXTDAY_FULLABS!=0 OR V_NEXTDAY_FSHLABS!=0) AND V_NEXTDAY_SCHLABS=0
              AND V_NXTDAYFULL_OODCNT=0 AND V_NXTDAYFULL_LVCNT=0) THEN --Verifyinng Previous day is Absent or not

             SELECT COUNT(ATTENDENCELOG.SYSID) INTO V_CNTEMPSYSID FROM ATTENDENCELOG,TBLDASHBOARD TBL
              WHERE TO_DATE(DATERECORDED,'DD-MM-YYYY')=TO_DATE(FROM_DATE,'DD-MM-YYYY') AND ATTENDENCELOG.EMPLOYEE_SYSID=V_EMPID
              AND TBL.ATTENDENCELOG_SYSID=ATTENDENCELOG.SYSID
              AND (to_char(to_date(INTIME, 'HH24:MI:SS'),'HH24:MI') <= to_char(to_date(V_STARTTIME, 'HH:MI PM'),'HH24:MI') 
              OR TO_CHAR(TO_DATE(INTIME, 'HH24:MI:SS'),'HH24:MI') >= TO_CHAR(TO_DATE(V_STARTTIME, 'HH:MI PM'),'HH24:MI'))
              AND (TO_CHAR(TO_DATE(OUTTIME, 'HH24:MI:SS'),'HH24:MI')  >= TO_CHAR(TO_DATE(V_ENDTIME, 'HH:MI PM'),'HH24:MI')
              OR ((((TBL.RC1='P' AND TBL.IN2 IS NULL) OR (TBL.RC2='P' AND TBL.IN3 IS NULL )  OR (TBL.RC3='P' AND TBL.IN4 IS NULL) OR (TBL.RC4='P' AND TBL.IN5 IS NULL)  OR (TBL.RC5='P' AND TBL.IN6 IS NULL) OR TBL.RC6='P'))  OR ( (TBL.RC1='O' AND TBL.IN2 IS NULL) OR (TBL.RC2='O' AND TBL.IN3 IS NULL)   OR (TBL.RC3='O' AND TBL.IN4 IS NULL) OR (TBL.RC4='O'AND TBL.IN5 IS NULL) 
                    OR (TBL.RC5='O'AND TBL.IN6 IS NULL) OR TBL.RC6='O')))  AND V_EMPID NOT IN(
              SELECT (E1.SYSID) FROM LEAVEFORMENTRY L,EMPLOYEE E1 WHERE L.EMPNO=E1.EMPNO 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.EMPNO=V_EMPNO AND L.ACTIVE='1')
              AND V_EMPID NOT IN(SELECT E2.SYSID FROM OODENTRY O, EMPLOYEE E2 WHERE O.EMPID=E2.SYSID 
              AND TO_DATE(FROM_DATE,'DD-MM-YY') BETWEEN TO_CHAR(TO_DATE(O.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE,'MM-DD-YYYY'),'DD-MON-YY') AND O.EMPID=V_EMPID AND O.ACTIVE=1)
              AND (TO_DATE(FROM_DATE,'DD-MON-YY') NOT IN (SELECT TO_CHAR(HOLIDAYDATE,'DD-MON-YY') FROM HOLIDAY)
              AND TO_CHAR(TO_DATE(FROM_DATE,'DD-MON-YY'),'DY')='SUN');--Defalut sunday is Holiday; 

          END IF; --Calculating Previous day END IF       

              SELECT COUNT(TO_NUMBER(EMPID)) INTO EMPIDCNT FROM TEMPSAP_EMPLOGABSENT WHERE EMPID=V_EMPID AND FULLAN IS NULL;

              IF(EMPIDCNT!=0) THEN
                SELECT FULLAN INTO V_FLDAYHLDAY FROM (SELECT FULLAN FROM TEMPSAP_EMPLOGABSENT WHERE EMPID=V_EMPID ORDER BY ABSENTTO DESC) WHERE ROWNUM <=1;
              END IF;
              --Previous is day Second half if is present or absent
              SELECT COUNT(SYSID) INTO V_FIRSTHALFPRESENT1 FROM ATTENDENCELOG
              WHERE TO_DATE(DATERECORDED,'DD-MM-YY')=TO_DATE(FROM_DATE,'DD-MM-YY')-1 AND EMPLOYEE_SYSID=V_EMPID
              AND TO_CHAR(TO_DATE(INTIME, 'HH24:MI:SS'),'HH24:MI') <= TO_CHAR(TO_DATE(V_STARTTIME, 'HH:MI PM'),'HH24:MI')
              AND  to_char(to_date(OUTTIME, 'HH24:MI:SS'),'HH24:MI')  >= to_char(to_date(V_BREAKOUT, 'HH:MI PM'),'HH24:MI')
              AND V_EMPID NOT IN(
              SELECT (E1.SYSID) FROM LEAVEFORMENTRY L,EMPLOYEE E1 WHERE L.EMPNO=E1.EMPNO 
              AND TO_DATE(FROM_DATE,'DD-MM-YY')-1 BETWEEN TO_CHAR(TO_DATE(L.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(L.TODATE, 'MM-DD-YYYY'), 'DD-MON-YY') AND L.EMPNO=V_EMPNO AND L.ACTIVE='1' AND L.FNTYPE='FN')
              AND V_EMPID NOT IN(SELECT E2.SYSID FROM OODENTRY O, EMPLOYEE E2 WHERE O.EMPID=E2.SYSID 
              AND TO_DATE(FROM_DATE,'DD-MM-YY')-1 BETWEEN TO_CHAR(TO_DATE(O.FROMDATE, 'MM-DD-YYYY'), 'DD-MON-YY')
              AND TO_CHAR(TO_DATE(O.TODATE,'MM-DD-YYYY'),'DD-MON-YY') AND O.EMPID=V_EMPID AND O.ACTIVE=1 AND O.DAYTYPE='FN');

           IF(EMPIDCNT>0 AND V_CNTEMPSYSID=0 AND V_CNTEMPSYSIDFN=0 AND V_CNTEMPSYSIDAN=0 AND V_HOLIDAYCNT=0
           AND V_FULLDAYLEAVE=0 AND V_FULLDAYOOD=0) THEN

              SELECT MAX(TO_DATE(ABSENTTO,'DD-MON-YY'))+1 INTO V_DATEOFAB FROM TEMPSAP_EMPLOGABSENT WHERE EMPID=V_EMPID;

              IF(V_DATEOFAB=TRIM(FROM_DATE) AND (V_FIRSTHALFPRESENT=0 AND V_SECONDHALFPRESENT=0
                AND V_SHLVFHABSENT=0 AND V_FHLVSHABSENT=0 AND V_FHOODSHABSENT=0 AND V_SHOODFHABSENT=0) AND V_FLDAYHLDAY IS NULL) THEN

                  UPDATE TEMPSAP_EMPLOGABSENT T SET T.ABSENTTO=FROM_DATE WHERE T.EMPID=V_EMPID AND
                  TO_DATE(ABSENTTO,'DD-MON-YY')=(SELECT MAX(TO_DATE(ABSENTTO,'DD-MON-YY')) FROM TEMPSAP_EMPLOGABSENT WHERE EMPID=V_EMPID);
              ELSE
                      -------------------------------------                    

                        IF(V_PRESENTEMPCNT!=0 AND V_FULLDAYPRESENT=0) THEN --First IF open

                           INSERT INTO TEMPSAP_EMPLOGABSENT(EMPID,DATEOFAB,STATUS,ABSENTFROM,ABSENTTO,EMPNO,FULLAN)       

                           SELECT (EMPLOYEE.SYSID),FROM_DATE,
                           CASE                                    
                           WHEN V_FIRSTHALFPRESENT!=0 THEN 'S'
                           WHEN V_SECONDHALFPRESENT!=0 THEN 'F'                   
                           ELSE 'FULL' END STATUS,FROM_DATE,FROM_DATE,(EMPLOYEE.EMPNO)EMPNO,
                           CASE                                    
                           WHEN V_FIRSTHALFPRESENT!=0 THEN 'S'
                           WHEN V_SECONDHALFPRESENT!=0 THEN 'F' END OODTYPE
                           FROM EMPLOYEE WHERE EMPNO=V_EMPNO;                     

                      ELSE --ELSE for First IF and EMPID not in TBLDASHBOARD then EMP in Leave or OOD or Absent 

                          IF(V_PRESENTEMPCNT=0 AND V_LEAVECNT=0 AND V_OODCNT=0) THEN --Absent

                              INSERT INTO TEMPSAP_EMPLOGABSENT(EMPID,DATEOFAB,STATUS,ABSENTFROM,ABSENTTO,EMPNO,FULLAN)

                              SELECT (EMPLOYEE.SYSID),FROM_DATE,'FULL'STATUS,FROM_DATE,FROM_DATE,(EMPLOYEE.EMPNO)EMPNO,NULL                               
                              FROM EMPLOYEE WHERE EMPNO=V_EMPNO
                              AND FROM_DATE NOT IN (SELECT HOLIDAYDATE FROM HOLIDAY WHERE 
                              TO_DATE(HOLIDAYDATE,'DD-MON-YY')=TO_DATE(FROM_DATE,'DD-MON-YY'))
                              AND V_SUNDAYCNT=0;                                                          
                          END IF;
                      END IF;
              END IF;   
           END IF;
      COMMIT;
    FROM_DATE:=FROM_DATE+1; --Increasing the date upto TODATE
    END LOOP; --While Date loop End    
    --end loop;
    COMMIT;
END LOOP;
CLOSE C_EMPID;
END;
4

1 回答 1

1

几个简单的例子如何改进它。我认为这还不够。

1) small change
a)

from:
    DELETE FROM TEMPSAP_EMPLOGABSENT;
  --DELETE FROM TMPEMPIDS;
    COMMIT;
to:
    /*TRUNCATE TABLE TEMPSAP_EMPLOGABSENT; Pointed out by Ben */
    EXECUTE IMMEDIATE 'TRUNCATE TABLE TEMPSAP_EMPLOGABSENT';
b)

IF(V_PRESENTEMPCNT!=0 AND V_FULLDAYPRESENT=0) THEN --First IF open
    INSERT INTO TEMPSAP_EMPLOGABSENT(EMPID,DATEOFAB,STATUS,ABSENTFROM,ABSENTTO,EMPNO,FULLAN)       
ELSE --ELSE for First IF and EMPID not in TBLDASHBOARD then EMP in Leave or OOD or Absent 
    IF(V_PRESENTEMPCNT=0 AND V_LEAVECNT=0 AND V_OODCNT=0) THEN --Absent
        INSERT INTO TEMPSAP_EMPLOGABSENT(EMPID,DATEOFAB,STATUS,ABSENTFROM,ABSENTTO,EMPNO,FULLAN)
    END IF;
END IF;

COMMIT; --- <---- add commit

2) medium change

from:
OPEN C_EMPID;
  LOOP
    FETCH C_EMPID INTO V_EMPID;
    EXIT WHEN C_EMPID%NOTFOUND;

to:
    OPEN C_EMPID;
    OPEN C_EMPID BULK COLLECT INTO V_EMPID; -- create it as nested table type
    OPEN C_EMPID;

    FOR indx IN 1..V_EMPID.COUNT LOOP
    ...

    -- exmaple use:
    SELECT EMPNO INTO V_EMPNO FROM EMPLOYEE WHERE SYSID=V_EMPID(indx);

3) huge change

With collections you can read all data at once and that work with it but that require some experience
from:
       SELECT EMPNO INTO V_EMPNO FROM EMPLOYEE WHERE SYSID=V_EMPID;

              SELECT G.CODE INTO V_GRADECODE FROM GRADE G,EMPLOYEE E
              WHERE E.GRADE_SYSID=G.SYSID AND E.SYSID=V_EMPID;        
to:


        SELECT EMPNO BULK COLLECT INTO V_EMPNO FROM EMPLOYEE /*WHERE SYSID=V_EMPID;*/ -- create it as nested table type

              SELECT G.CODE BULK COLLECT INTO V_GRADECODE FROM GRADE G,EMPLOYEE E -- create it as nested table type
              WHERE E.GRADE_SYSID=G.SYSID /*AND E.SYSID=V_EMPID;*/
于 2013-06-12T12:16:45.897 回答