Пакет PL / SQL продолжает работать вечно - PullRequest
0 голосов
/ 08 июня 2018

Я написал приведенный ниже пакет для загрузки данных из промежуточных таблиц в действующие таблицы.Есть две категории данных, на основании которых будет определена целевая живая таблица.

, когда я запускаю процедуру, она продолжает работать (у меня менее 1000 строк в промежуточной таблице) в sqlразработчик, и через некоторое время соединение возобновляется.

если я делаю что-то не так, любые указатели будут высоко оценены.

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 голосов
/ 09 июня 2018

Ваш цикл 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;

И, как сказал Боб Джарвис, для не объемных циклов курсора notfound проверка должна производиться сразу после fetch, иначе последняя извлеченная строка будет обработана дважды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...