PL / SQL包继续运行

时间:2018-06-08 19:41:41

标签: sql oracle plsql

我编写了以下软件包,用于将登台表中的数据加载到实时表中。 有两类数据,根据这两类数据确定目标实时表。

当我运行该程序时,它继续运行(我在登台表中少于1000行) 在sql developer中,一段时间后连接就会停止。

我做错了什么,任何指针都会受到高度赞赏。

CREATE OR REPLACE PACKAGE ACADEMY_DATA_STG_2_SUMM_PKG
AS
CURSOR STG_CUR IS
    SELECT SIF_ID, FLT_CODE FROM STG_FILES 
    WHERE FLT_CODE IN ('ACP', 'ATR')
    AND SIF_PROCESS_FLAG = 'N';

CURSOR TECH_CUR(P_SIF_ID IN NUMBER) IS
    SELECT 
    ATR_ID, ATR_AREA, ATR_REGION,D.DLR_KEY,ATR_COMPLIANT,ATR_TOTAL_ACTIVE_STAFF,ATR_ELECTRICAL_REQD,
    ATR_ELECTRICAL_COMPLAINT,ATR_ENGINE_REQD,ATR_ENGINE_COMPLAINT,ATR_TRANSMISSION_REQD,
    ATR_TRANSMISSION_COMPLAINT,ATR_CHASIS_REQD,ATR_CHASIS_COMPLAINT,ATR_EMOBILITY_REQD,
    ATR_EMOBILITY_COMPLAINT,ATR_MASTER_REQD,ATR_MASTER_COMPLAINT,ATR_EGOLF_REQD,
    ATR_EGOLF_COMPLAINT,TO_CHAR(ATR_DATE_CREATED,'YYYYMM') YEARMONTH 
    FROM STG_ACADEMY_TECH_READINESS_REC ATR, DW_DEALER_DIM D
    WHERE ATR.ATR_DEALER_CODE = D.DLR_CODE
    AND ATR_PROCESS_FLAG = 'N'
    AND ((SIF_ID = P_SIF_ID) OR (P_SIF_ID IS NULL));

CURSOR CERT_CUR(P_SIF_ID IN NUMBER) IS
    SELECT 
    ACR_ID, ACR_AREA,ACR_REGION,D.DLR_KEY,ACR_PARTS_CERTIFIED,ACR_PARTS_ACTIVE,
    ACR_PARTS_CERTIFIED_PCT,ACR_SALES_CERTIFIED,ACR_SALES_ACTIVE,ACR_SALES_CERTIFIED_PCT,
    ACR_SERVICE_CERTIFIED,ACR_SERVICE_ACTIVE,ACR_SERVICE_CERTIFIED_PCT,ACR_TECH_CERTIFIED,
    ACR_TECH_ACTIVE,ACR_TECH_CERTIFIED_PCT,ACR_TOTAL_CERTIFIED,ACR_TOTAL_ACTIVE,
    ACR_TOTAL_CERTIFIED_PCT,TO_CHAR(ACR_DATE_CREATED,'YYYYMM') YEARMONTH 
    FROM STG_ACADEMY_CERTIFICATION_REC ACP, DW_DEALER_DIM D
    WHERE ACP.ACR_DEALER_CODE = D.DLR_CODE
    AND ACR_PROCESS_FLAG = 'N'
    AND ((SIF_ID = P_SIF_ID) OR (P_SIF_ID IS NULL));

TYPE TECH_TBL IS TABLE OF TECH_CUR%ROWTYPE;

TYPE CERT_TBL IS TABLE OF CERT_CUR%ROWTYPE;

PROCEDURE ACADEMY_DATA_PROCESS;

PROCEDURE INSERT_CERT_DATA(CERT_ARR IN CERT_TBL);
PROCEDURE INSERT_TECH_DATA(TECH_ARR IN TECH_TBL);

END ACADEMY_DATA_STG_2_SUMM_PKG;
/
CREATE OR REPLACE PACKAGE BODY ACADEMY_DATA_STG_2_SUMM_PKG
AS
PROCEDURE ACADEMY_DATA_PROCESS
IS
TECH_ARR TECH_TBL := TECH_TBL();
CERT_ARR CERT_TBL := CERT_TBL();

LV_SIF_ID NUMBER;
LV_FLT_CODE VARCHAR2(10);
LV_PRS_ID NUMBER;

LV_ERR_MSG VARCHAR2(500);
LV_ERROR_SECTION VARCHAR2(100);
BEGIN
    IF STG_CUR%ISOPEN THEN
        CLOSE STG_CUR;
    END IF;

    OPEN STG_CUR;
    LOOP
        FETCH STG_CUR INTO LV_SIF_ID, LV_FLT_CODE;
        --UPDATE PROCESS STATS
        LV_ERROR_SECTION := 'INSERT PROCESS STATS';

        INSERT INTO PROCESS_STATS(PCG_CODE, SIF_ID, PRS_START_DATETIME)
        VALUES('ADI_ODSLOAD', LV_SIF_ID, SYSTIMESTAMP)
        RETURNING PRS_ID INTO LV_PRS_ID;

        --UPDATE STG_FILES
        LV_ERROR_SECTION := 'UPDATE STG_FILES';

        UPDATE STG_FILES
        SET SIF_PROCESS_FLAG = 'P'
        WHERE SIF_ID = LV_SIF_ID;

        IF LV_FLT_CODE = 'ATR' THEN
        --TECHNICAL READINESS   
        LV_ERROR_SECTION := 'TECH READINESS LOOP';      
        OPEN TECH_CUR(LV_SIF_ID);
        LOOP
            FETCH TECH_CUR BULK COLLECT INTO TECH_ARR LIMIT 1000;
            IF TECH_ARR.COUNT <> 0 THEN
                INSERT_TECH_DATA(TECH_ARR);
            END IF;
            EXIT WHEN TECH_CUR%NOTFOUND;
        END LOOP;
        CLOSE TECH_CUR;
        ELSE
        --CERTIFICATION PERCENTAGE
        LV_ERROR_SECTION := 'CERTIFICATION PERCENTAGE LOOP';
        OPEN CERT_CUR(LV_SIF_ID);
        LOOP
            FETCH CERT_CUR BULK COLLECT INTO CERT_ARR LIMIT 1000;
            IF CERT_ARR.COUNT <> 0 THEN
                INSERT_CERT_DATA(CERT_ARR);
            END IF;
        END LOOP;
        CLOSE CERT_CUR;
        END IF;
        EXIT WHEN STG_CUR%NOTFOUND;

        LV_ERROR_SECTION := 'UPDATE PROCESS_STATS';

        UPDATE PROCESS_STATS
        SET PLS_END_DATETIME = SYSTIMESTAMP,
        PRS_ERRORED = LV_ERR_MSG
        WHERE PRS_ID = LV_PRS_ID;

    END LOOP;
    CLOSE STG_CUR;
EXCEPTION
WHEN OTHERS THEN
    LV_ERR_MSG := SQLCODE||SQLERRM;
    DBMS_OUTPUT.PUT_LINE('ERROR OCCURED AT: '||LV_ERROR_SECTION||' ERROR DESCRIPTION: '||LV_ERR_MSG);
    ROLLBACK;
    UPDATE PROCESS_STATS
        SET PLS_END_DATETIME = SYSTIMESTAMP,
        PRS_ERRORED = LV_ERR_MSG
        WHERE PRS_ID = LV_PRS_ID;
    COMMIT;

END ACADEMY_DATA_PROCESS;

PROCEDURE INSERT_CERT_DATA(CERT_ARR IN CERT_TBL)
IS 
LV_ERR_MSG VARCHAR2(500);
BEGIN
    FOR I IN CERT_ARR.FIRST..CERT_ARR.LAST
    LOOP
    BEGIN
        INSERT INTO DW_ACADEMY_CERTIFICATION_SUMM
        (YEARMONTH,
        RGN_CODE,
        AREA_CODE,
        ACS_PARTS_CERTIFIED,
        ACS_PARTS_ACTIVE,
        ACS_PARTS_CERTIFIED_PCT,
        ACS_SALES_CERTIFIED,
        ACS_SALES_ACTIVE,
        ACS_SALES_CERTIFIED_PCT,
        ACS_SERVICE_CERTIFIED,
        ACS_SERVICE_ACTIVE,
        ACS_SERVICE_CERTIFIED_PCT,
        ACS_TECH_CERTIFIED,
        ACS_TECH_ACTIVE,
        ACS_TECH_CERTIFIED_PCT,
        ACS_TOTAL_CERTIFIED,
        ACS_TOTAL_ACTIVE,
        ACS_TOTAL_CERTIFIED_PCT
        )
        VALUES(
        CERT_ARR(I).YEARMONTH,
        CERT_ARR(I).ACR_REGION,
        CERT_ARR(I).ACR_AREA,
        REGEXP_REPLACE(CERT_ARR(I).ACR_PARTS_CERTIFIED,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_PARTS_ACTIVE,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_PARTS_CERTIFIED_PCT,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_SALES_CERTIFIED,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_SALES_ACTIVE,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_SALES_CERTIFIED_PCT,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_SERVICE_CERTIFIED,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_SERVICE_ACTIVE,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_SERVICE_CERTIFIED_PCT,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_TECH_CERTIFIED,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_TECH_ACTIVE,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_TECH_CERTIFIED_PCT,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_TOTAL_CERTIFIED,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_TOTAL_ACTIVE,'[^0-9.-]+', ''),
        REGEXP_REPLACE(CERT_ARR(I).ACR_TOTAL_CERTIFIED_PCT'[^0-9.-]+', '')
        );

        UPDATE STG_ACADEMY_CERTIFICATION_REC
        SET ACR_PROCESS_FLAG = 'Y',
        PRC_CODE = 'S40',
        ACR_ERR_MSG = LV_ERR_MSG
        WHERE ACR_ID = CERT_ARR(I).ACR_ID;

        COMMIT;

    EXCEPTION
    WHEN OTHERS THEN
        LV_ERR_MSG := SQLCODE||SQLERRM;
        ROLLBACK;

        UPDATE STG_ACADEMY_CERTIFICATION_REC
        SET ACR_PROCESS_FLAG = 'Y',
        PRC_CODE = 'O40',
        ACR_ERR_MSG = LV_ERR_MSG
        WHERE ACR_ID = CERT_ARR(I).ACR_ID;

        COMMIT;
    END;
    END LOOP;
END INSERT_CERT_DATA;

PROCEDURE INSERT_TECH_DATA(TECH_ARR IN TECH_TBL)
IS
LV_ERR_MSG VARCHAR2(500);
BEGIN
    FOR I IN TECH_ARR.FIRST..TECH_ARR.LAST 
    LOOP
        BEGIN
            INSERT INTO DW_ACADEMY_TECH_READINESS_SUM(
            YEARMONTH,
            RGN_CODE,
            AREA_CODE,
            ATS_COMPLIANT,
            ATS_TOTAL_ACTIVE_STAFF,
            ATS_ELECTRICAL_REQD,
            ATS_ELECTRICAL_COMPLAINT,
            ATS_ENGINE_REQD,
            ATS_ENGINE_COMPLAINT,
            ATS_TRANSMISSION_REQD,
            ATS_TRANSMISSION_COMPLAINT,
            ATS_CHASIS_REQD,
            ATS_CHASIS_COMPLAINT,
            ATS_EMOBILITY_REQD,
            ATS_EMOBILITY_COMPLAINT,
            ATS_MASTER_REQD,
            ATS_MASTER_COMPLAINT,
            ATS_EGOLF_REQD,
            ATS_EGOLF_COMPLAINT)
            VALUES
            (TECH_ARR(I).YEARMONTH,
            TECH_ARR(I).ATR_REGION,
            TECH_ARR(I).ATR_AREA,
            TECH_ARR(I).ATR_COMPLIANT,
            REGEXP_REPLACE(TECH_ARR(I).ATR_TOTAL_ACTIVE_STAFF,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_ELECTRICAL_REQD,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_ELECTRICAL_COMPLAINT,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_ENGINE_REQD,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_ENGINE_COMPLAINT,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_TRANSMISSION_REQD,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_TRANSMISSION_COMPLAINT,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_CHASIS_REQD,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_CHASIS_COMPLAINT,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_EMOBILITY_REQD,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_EMOBILITY_COMPLAINT,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_MASTER_REQD,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_MASTER_COMPLAINT,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_EGOLF_REQD,'[^0-9.-]+', ''),
            REGEXP_REPLACE(TECH_ARR(I).ATR_EGOLF_COMPLAINT'[^0-9.-]+', ''),
            );

            UPDATE STG_ACADEMY_TECH_READINESS_REC
            SET ATR_PROCESS_FLAG = 'Y',
            PRC_CODE = 'S40',
            ATR_ERR_MSG = LV_ERR_MSG
            WHERE ATR_ID = TECH_ARR(I).ATR_ID;

            COMMIT;
        EXCEPTION 
            WHEN OTHERS THEN
            LV_ERR_MSG := SQLCODE||SQLERRM;
            ROLLBACK;

            UPDATE STG_ACADEMY_TECH_READINESS_REC
            SET ATR_PROCESS_FLAG = 'Y',
            PRC_CODE = 'O40',
            ATR_ERR_MSG = LV_ERR_MSG
            WHERE ATR_ID = TECH_ARR(I).ATR_ID;

            COMMIT;
        END;
    END LOOP;
END INSERT_TECH_DATA;
END ACADEMY_DATA_STG_2_SUMM_PKG;

1 个答案:

答案 0 :(得分:3)

您的CERT_CUR循环无法退出:

    LOOP
        FETCH CERT_CUR BULK COLLECT INTO CERT_ARR LIMIT 1000;
        IF CERT_ARR.COUNT <> 0 THEN
            INSERT_CERT_DATA(CERT_ARR);
        END IF;
    END LOOP;

应该是:

    LOOP
        FETCH CERT_CUR BULK COLLECT INTO CERT_ARR LIMIT 1000;
        IF CERT_ARR.COUNT <> 0 THEN
            INSERT_CERT_DATA(CERT_ARR);
        END IF;
        EXIT WHEN CERT_CUR%NOTFOUND;
    END LOOP;

正如Bob Jarvis所说,对于非批量游标循环,notfound检查应该在fetch之后,或者最后一行被提取两次。