我编写了以下软件包,用于将登台表中的数据加载到实时表中。 有两类数据,根据这两类数据确定目标实时表。
当我运行该程序时,它继续运行(我在登台表中少于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;
答案 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
之后,或者最后一行被提取两次。