我正在破坏'POST_DAILY_GL'过程,它正在调用另一个过程'IN_LEDGER_STAT_DAILY',该过程正在'LEDGER_STAT_DLY'表中插入/更新数据。 “ POST_DAILY_GL”过程每天都会在prod中运行,但是当我在测试环境中运行该过程时,要花费150万条记录是永远的。我已经在每1000条记录中添加了一次commit,这表明大约需要25个小时。发布150万条记录。 我可以要求建议在此过程中可以进行哪些改进。
***--'POST_DAILY_GL' procedure***
PROCEDURE POST_DAILY_GL(V_RUN_DATE NUMBER DEFAULT 0) AS
BEGIN
IF V_RUN_DATE = 0 THEN
SELECT INSTR_AS_OF_DATE INTO V_DATE FROM AS_OF_DATE;
ELSE
V_DATE := TO_DATE(LPAD(V_RUN_DATE, 8, '0'),'mmddyyyy');
END IF;
i :=0;
V_DATE_PARAM := RETURN_DATE(V_DATE);
V_SQL := q'[SELECT A.ACCOUNT_TYPE, B.FIN_ELEM, A.ORG_UNIT_ID, A.GL_ACCOUNT_ID, B.CMN_COA_ID, B.PROD1, B.PROD2, B.PROD3,
SUM(CURRENT_BAL) AS CB_SUM, SUM(AVG_BAL) AS AB_SUM, B.FLAG1 FROM DAILYGL A, AL_LOOKUP B
WHERE A.GL_ACCOUNT_ID = B.GL_ACCT AND A.AS_OF_DATE = :V_DATE_PARAM
GROUP BY A.ACCOUNT_TYPE, B.FIN_ELEM, A.ORG_UNIT_ID, A.GL_ACCOUNT_ID,B.CMN_COA_ID, B.PROD1,
B.PROD2, B.PROD3, A.AS_OF_DATE, B.FLAG1]';
OPEN seq FOR V_SQL using V_DATE_PARAM;
LOOP
V_SWITCH := 1;
FETCH seq INTO
V_ACCT_TYPE,
V_FIN,
V_ORG_UNIT_ID,
V_GL_ACCOUNT_ID,
V_CMN_COA_ID,
V_PROD1,
V_PROD2,
V_PROD3,
V_END_BAL, --cb
V_AVG_BAL, --ab
V_FLAG;
EXIT WHEN seq%NOTFOUND;
IF V_FLAG = 'Y' THEN
V_SWITCH := -1;
ELSE
V_SWITCH := 1;
END IF;
IF V_ACCT_TYPE = 5 OR V_ACCT_TYPE = 10 OR V_ACCT_TYPE = 20 OR V_ACCT_TYPE = 35 THEN
V_SWITCH := V_SWITCH * -1;
END IF;
IF (V_END_BAL <> 0 OR V_AVG_BAL <>0) THEN
IF V_ACCT_TYPE = 1 OR V_ACCT_TYPE = 5 OR V_ACCT_TYPE = 10 OR V_ACCT_TYPE = 90 THEN
V_FIN1 := SUBSTR(V_FIN,1,2) || '100';
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN1,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE_PARAM,V_SWITCH * V_END_BAL);
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE_PARAM,V_SWITCH * V_AVG_BAL);
ELSE
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE_PARAM,V_SWITCH * V_END_BAL);
END IF;
END IF;
i:=i + 1;
if mod(i, 1000)=0 then
insert into AL_STARTSTOP_SAC values('1000 recs committed at '||to_char(sysdate,'dd-mon-yyyy hh:mi:ss am'));
commit;
end if;
END LOOP;
CLOSE seq;
END POST_DAILY_GL;
***--'IN_LEDGER_STAT_DAILY' procedure which is inserting/updating data***
PROCEDURE IN_LEDGER_STAT_DAILY
(
V_IDENTITY_CODE NUMBER,
V_CONSOLIDATION_CD NUMBER,
V_FINANCIAL_ELEM_ID NUMBER,
V_ORG_UNIT_ID NUMBER,
V_GL_ACCOUNT_ID NUMBER,
V_COMMON_COA_ID NUMBER,
V_PRODUCT_1_ID NUMBER,
V_PRODUCT_ID NUMBER,
V_PRODUCT_3_ID NUMBER,
V_DATE DATE,
V_AMOUNT NUMBER,
V_MEMO_GL_ACCOUNT_ID NUMBER DEFAULT 0,
V_POSTINGTYPE CHAR DEFAULT 'N',
V_BALANCE_TYPE_CD NUMBER DEFAULT 0
)
IS
V_CNT NUMBER;
V_MONTH CHAR(2);
V_MO NUMBER;
V_YEAR_S NUMBER;
BEGIN
IF V_POSTINGTYPE = 'N' THEN
IF NVL(V_AMOUNT,0) <> 0 THEN
V_MO := (MONTH(V_DATE));
V_MONTH := LPAD(V_MO,2,'0');
V_YEAR_S := (YEAR(V_DATE));
SELECT
COUNT(*) INTO V_CNT
FROM LEDGER_STAT_DLY A
WHERE
IDENTITY_CODE = NVL(V_IDENTITY_CODE,0)
AND YEAR_S = NVL(V_YEAR_S,0)
AND MONTH_NO = NVL(V_MONTH,0)
AND CONSOLIDATION_CD = NVL(V_CONSOLIDATION_CD,0)
AND FINANCIAL_ELEM_ID = NVL(V_FINANCIAL_ELEM_ID,0)
AND ORG_UNIT_ID = NVL(V_ORG_UNIT_ID,0)
AND GL_ACCOUNT_ID = NVL(V_GL_ACCOUNT_ID,0)
AND COMMON_COA_ID = NVL(V_COMMON_COA_ID,0)
AND PRODUCT_1_ID = NVL(V_PRODUCT_1_ID,0)
AND PRODUCT_ID = NVL(V_PRODUCT_ID,0)
AND PRODUCT_3_ID = NVL(V_PRODUCT_3_ID,0)
AND COST_TYPE_ID = NVL(V_MEMO_GL_ACCOUNT_ID,0)
AND BALANCE_TYPE_CD = NVL(V_BALANCE_TYPE_CD,0) ;
IF V_CNT = 0 THEN
INSERT INTO LEDGER_STAT_DLY VALUES(
NVL(V_IDENTITY_CODE,0),
NVL(V_YEAR_S,0) ,
NVL(V_MONTH,0) ,
'D',
NVL(V_CONSOLIDATION_CD,0),
NVL(V_FINANCIAL_ELEM_ID,0),
NVL(V_ORG_UNIT_ID,0) ,
NVL(V_GL_ACCOUNT_ID,0) ,
NVL(V_COMMON_COA_ID,0) ,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
NVL(V_PRODUCT_1_ID,0) ,
NVL(V_PRODUCT_ID,0) ,
NVL(V_PRODUCT_3_ID,0) ,
TRUNC(NVL(V_ORG_UNIT_ID,0) / 10000000),
'USD',
NULL,
NVL(V_BALANCE_TYPE_CD,0),
0,
NVL(V_MEMO_GL_ACCOUNT_ID,0),
0
);
END IF;
CASE DAY(V_DATE)
WHEN 1 THEN
UPDATE LEDGER_STAT_DLY A
SET DAY_01 = NVL(DAY_01,0) + NVL(V_AMOUNT,0)
WHERE IDENTITY_CODE = NVL(V_IDENTITY_CODE,0)
AND YEAR_S = NVL(V_YEAR_S,0)
AND MONTH_NO = NVL(V_MONTH,0)
AND CONSOLIDATION_CD = NVL(V_CONSOLIDATION_CD,0)
AND FINANCIAL_ELEM_ID = NVL(V_FINANCIAL_ELEM_ID,0)
AND ORG_UNIT_ID = NVL(V_ORG_UNIT_ID,0)
AND GL_ACCOUNT_ID = NVL(V_GL_ACCOUNT_ID,0)
AND COMMON_COA_ID = NVL(V_COMMON_COA_ID,0)
AND PRODUCT_1_ID = NVL(V_PRODUCT_1_ID,0)
AND PRODUCT_ID = NVL(V_PRODUCT_ID,0)
AND PRODUCT_3_ID = NVL(V_PRODUCT_3_ID,0)
AND COST_TYPE_ID = NVL(V_MEMO_GL_ACCOUNT_ID,0)
AND BALANCE_TYPE_CD = NVL(V_BALANCE_TYPE_CD,0);
-- and same logic applies for all other days (2-31) of month
ELSE
DBMS_OUTPUT.PUT_LINE('Please enter valid input for Day#: ');
END CASE;
END IF;
END IF; --CLOSURE FOR POSTING TYPE IF STATEMENT
END IN_LEDGER_STAT_DAILY;
很抱歉,如果有人发现代码段太长。我将大部分代码放在这里,因此不会在不知不觉中遗漏某些东西。期待提出建议,并提前感谢您的帮助。