我使用bulkcollect制作了这个程序。 现在,我想让另一个程序只使用for循环执行相同的任务,但不使用bulkcollect或游标。 请帮帮我,怎么做?
PROCEDURE PR_TRIAL_BAL_BULKWITHOUTCUR IS
VAR_OF_TYP_TBL TYP_TBL;
BEGIN
SELECT * BULK COLLECT INTO VAR_OF_TYP_TBL
FROM (SELECT NAME, SUM(CREDIT) AS CREDIT, SUM(DEBIT) AS DEBIT
FROM (SELECT (SELECT GL_NAME
FROM QM_GL
WHERE QM_GL.GL_ID = QT_ACCOUNTING.GL_ID) AS NAME,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'CR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS CREDIT,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'DR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS DEBIT
FROM QT_ACCOUNTING, QM_ACCOUNTING_PERIOD
WHERE QT_ACCOUNTING.VALUE_DATE BETWEEN
QM_ACCOUNTING_PERIOD.PERIODFROM AND
QM_ACCOUNTING_PERIOD.PERIODTO
AND QM_ACCOUNTING_PERIOD.STATUS = 'O')
GROUP BY NAME);
FOR I IN 1 .. VAR_OF_TYP_TBL.COUNT LOOP
IF (VAR_OF_TYP_TBL(I).CREDIT - VAR_OF_TYP_TBL(I).DEBIT) > 0 THEN
INSERT INTO TBL_TRIAL_BALANCE_REPORT
VALUES
(VAR_OF_TYP_TBL(I).NAME,
(VAR_OF_TYP_TBL(I).CREDIT - VAR_OF_TYP_TBL(I).DEBIT),
0);
END IF;
IF (VAR_OF_TYP_TBL(I).DEBIT - VAR_OF_TYP_TBL(I).CREDIT) > 0 THEN
INSERT INTO TBL_TRIAL_BALANCE_REPORT
VALUES
(VAR_OF_TYP_TBL(I).NAME,
0,
(VAR_OF_TYP_TBL(I).DEBIT - VAR_OF_TYP_TBL(I).CREDIT));
END IF;
END LOOP;
VAR_OF_TYP_TBL.DELETE;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
BEGIN
VAR_OF_TYP_TBL.DELETE;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END;
答案 0 :(得分:1)
免责声明:此解决方案不建议使用,不应使用
我用它污染这个网站的唯一原因是因为这是OP想要的......
请不要低估这个答案
这是一个不在显式光标上的循环
PROCEDURE PR_TRIAL_BALANCE_FORLOOP IS
max_j NUMBER;
v_name QM_GL.GL_NAME%TYPE;
v_debit NUMBER;
v_credit NUMBER;
BEGIN
SELECT count(*)
INTO max_j
FROM (SELECT NAME, SUM(CREDIT) AS CREDIT, SUM(DEBIT) AS DEBIT
FROM (SELECT (SELECT GL_NAME
FROM QM_GL
WHERE QM_GL.GL_ID = QT_ACCOUNTING.GL_ID) AS NAME,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'CR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS CREDIT,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'DR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS DEBIT
FROM QT_ACCOUNTING, QM_ACCOUNTING_PERIOD
WHERE QT_ACCOUNTING.VALUE_DATE BETWEEN
QM_ACCOUNTING_PERIOD.PERIODFROM AND
QM_ACCOUNTING_PERIOD.PERIODTO
AND QM_ACCOUNTING_PERIOD.STATUS = 'O')
GROUP BY NAME);
FOR j IN 1..max_j LOOP
select tt.name, tt.credit, tt.debit INTO v_name, v_credit, v_debit
from (
SELECT rownum rn, NAME, SUM(CREDIT) AS CREDIT, SUM(DEBIT) AS DEBIT
FROM (SELECT (SELECT GL_NAME
FROM QM_GL
WHERE QM_GL.GL_ID = QT_ACCOUNTING.GL_ID) AS NAME,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'CR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS CREDIT,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'DR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS DEBIT
FROM QT_ACCOUNTING, QM_ACCOUNTING_PERIOD
WHERE QT_ACCOUNTING.VALUE_DATE BETWEEN
QM_ACCOUNTING_PERIOD.PERIODFROM AND
QM_ACCOUNTING_PERIOD.PERIODTO
AND QM_ACCOUNTING_PERIOD.STATUS = 'O')
GROUP BY NAME ) tt
where tt.rn = j;
IF (v_CREDIT - v_DEBIT) > 0 THEN
INSERT INTO TBL_TRIAL_BALANCE_REPORT
VALUES
(v_NAME,
(v_CREDIT - v_DEBIT),
0);
END IF;
IF (v_DEBIT - v_CREDIT) > 0 THEN
INSERT INTO TBL_TRIAL_BALANCE_REPORT
VALUES
(v_NAME,
0,
(v_DEBIT - v_CREDIT));
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
请注意,这是一个非常糟糕的解决方案,它在循环上运行,每次只查询一条记录。这不是那种做事的方式,但这是满足您要求的方式
答案 1 :(得分:0)
您可以将其作为单个insert select
执行:
INSERT INTO TBL_TRIAL_BALANCE_REPORT
SELECT NAME
, case when CREDIT > DEBIT then CREDIT - DEBIT else 0 end
, case when DEBIT > CREDIT then DEBIT - CREDIT else 0 end
FROM (SELECT NAME, SUM(CREDIT) AS CREDIT, SUM(DEBIT) AS DEBIT
FROM (SELECT (SELECT GL_NAME
FROM QM_GL
WHERE QM_GL.GL_ID = QT_ACCOUNTING.GL_ID) AS NAME,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'CR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS CREDIT,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'DR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS DEBIT
FROM QT_ACCOUNTING, QM_ACCOUNTING_PERIOD
WHERE QT_ACCOUNTING.VALUE_DATE BETWEEN
QM_ACCOUNTING_PERIOD.PERIODFROM AND
QM_ACCOUNTING_PERIOD.PERIODTO
AND QM_ACCOUNTING_PERIOD.STATUS = 'O')
GROUP BY NAME);
答案 2 :(得分:0)
PROCEDURE PR_TRIAL_BALANCE_FORLOOP IS
I NUMBER(6):=0;
BEGIN
FOR I IN (SELECT NAME, SUM(CREDIT) AS CREDIT, SUM(DEBIT) AS DEBIT
FROM (SELECT (SELECT GL_NAME
FROM QM_GL
WHERE QM_GL.GL_ID = QT_ACCOUNTING.GL_ID) AS NAME,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'CR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS CREDIT,
DECODE(QT_ACCOUNTING.TRANS_TYPE,
'DR',
(QT_ACCOUNTING.TRANS_AMOUNT),
0.00) AS DEBIT
FROM QT_ACCOUNTING, QM_ACCOUNTING_PERIOD
WHERE QT_ACCOUNTING.VALUE_DATE BETWEEN
QM_ACCOUNTING_PERIOD.PERIODFROM AND
QM_ACCOUNTING_PERIOD.PERIODTO
AND QM_ACCOUNTING_PERIOD.STATUS = 'O')
GROUP BY NAME)
LOOP
IF (I.CREDIT - I.DEBIT) > 0 THEN
INSERT INTO TBL_TRIAL_BALANCE_REPORT
VALUES
(I.NAME,
(I.CREDIT - I.DEBIT),
0);
END IF;
IF (I.DEBIT - I.CREDIT) > 0 THEN
INSERT INTO TBL_TRIAL_BALANCE_REPORT
VALUES
(I.NAME,
0,
(I.DEBIT - I.CREDIT));
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;