【问题标题】:Procedure is not ending程序没有结束
【发布时间】:2019-07-29 17:44:34
【问题描述】:

我对 PLSQL 和堆栈溢出非常陌生。我已经编写了 PLSQL 代码来在我的作业中发布虚拟条目。我编写了以下代码来使用动态 SQL 发布条目(我已经在这个论坛和互联网上阅读过它并尝试使用它)。我面临的一个问题是这个过程没有结束/退出。我已经多次查看它,但我似乎找到了代码。

您能否建议需要更新的内容,以便我可以成功发布条目?

提前感谢您的帮助。

PS:这是我在这里的第一个问题。如果需要任何更新,请告诉我。

--package spec
CREATE OR REPLACE PACKAGE POST_ENTRIES AS
PROCEDURE POST_DAILY() ;

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 
);

END POST_ENTRIES;
/


--package body
CREATE OR REPLACE PACKAGE BODY POST_ENTRIES AS


PROCEDURE POST_DAILY() AS

--BASE VARIABLES

i number := 0;
DS NUMBER := 82;
j number;
V_NEXT_WORKING_DATE DATE;

V_IDENTITY_CODE CONSTANT NUMBER(6):=112233;
V_CONSOLIDATION_CD   CONSTANT NUMBER(3):=100;
v_RECORDS_EXPECTED number;
v_RECORDS_ACTUAL number;


-- variables store result of dynamic cursor
V_SQL   VARCHAR2(2500);

TYPE  V_CURSOR IS REF CURSOR;

seq  V_CURSOR;

V_ORG_UNIT_ID           LEDGER_STAT_DLY.ORG_UNIT_ID%TYPE;
V_GL_ACCOUNT_ID         LEDGER_STAT_DLY.GL_ACCOUNT_ID%TYPE;
V_CMN_COA_ID            LEDGER_STAT_DLY. COMMON_COA_ID%TYPE;
V_PROD1                 LEDGER_STAT_DLY.PRODUCT_1_ID%TYPE;
V_PROD2                 LEDGER_STAT_DLY.PRODUCT_ID%TYPE;
V_PROD3                 LEDGER_STAT_DLY.PRODUCT_3_ID%TYPE;
V_DATE                  DAILYGL.AS_OF_DATE%TYPE;
V_POSTED                APPLICATION_TABLE_RECORD_COUNT.DLY_AS_OF_DATE%TYPE;
V_UPPER                 number;
V_DATE_PARAM            DATE;
V_END_BAL               NUMBER;
V_AVG_BAL               NUMBER;
V_SWITCH                NUMBER(1);
V_FLAG                  AL_LOOKUP.FLAG1%TYPE;
V_FIN                   AL_LOOKUP.FIN_ELEM%TYPE;
V_FIN1                  AL_LOOKUP.FIN_ELEM%TYPE;
V_ACCT_TYPE             NUMBER(2);


BEGIN


V_DATE:= '31-may-2019' -- this is getting returned from function but I've placed value here directly.

V_NEXT_WORKING_DATE := '03-Jun-2019'  -- this is getting returned from function but I've placed value here directly.

V_DATE_PARAM :=  V_DATE ; --POSTING DATE, START WITH V_DATE IT WILL INCREMENT INSIDE  WHILE LOOP. EXIT WHEN V_DATE_PARAM = V_NEXT_WORKING_DATE

------------------------------

WHILE V_DATE_PARAM < V_NEXT_WORKING_DATE

loop        

        V_SQL := '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_TEST A, AL_LOOKUP B
                 WHERE A.GL_ACCOUNT_ID = B.GL_ACCT AND A.AS_OF_DATE = '||chr(39)||V_DATE||chr(39)|| 
                 ' and rownum <=3 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;

            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,  
                            V_AVG_BAL,  
                            V_FLAG;                                 

                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;

            END LOOP;

    CLOSE seq;

   V_DATE_PARAM := V_DATE_PARAM +1;

end loop;

END POST_DAILY; 

-------IN_LEDGER_STAT_DAILY procedure

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_D      NUMBER;
V_DAY    CHAR(6);
V_MONTH CHAR(2);
V_MO NUMBER;
V_YEAR_S NUMBER;

-- variables store result of dynamic cursor
V_SL   VARCHAR2(2500);
V_TARGET_COLUMN VARCHAR2(6 CHAR);
k number := 0;


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));
                V_D := (DAY(V_DATE));
                V_DAY := 'DAY_' || lpad(V_D, 2, '0');

                SELECT /*+ index(a LEDGER_STAT_DLY_IDX02_IN) */ 
                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',                             -- ISO_CURRENCY_CD
                    NULL,                              -- CURRENCY_TYPE_CD
                    NVL(V_BALANCE_TYPE_CD,0),
                    0,                                 -- VOLUME_ID
                    NVL(V_MEMO_GL_ACCOUNT_ID,0),       -- COST_TYPE_ID
                    0                                  -- CHANNEL_ID
                    );
              END IF;

             EXECUTE IMMEDIATE UTL_LMS.FORMAT_MESSAGE('UPDATE /*+ index(a LEDGER_STAT_DLY_IDX02_IN) */ LEDGER_STAT_DLY A
                           SET %s =  NVL(%s,0) + NVL(:THE_AMOUNT,0)
                           WHERE IDENTITY_CODE =  NVL(:THE_IDENTITY_CODE,0)
                              AND YEAR_S =  NVL(:THE_YEAR_S,0)
                              AND MONTH_NO = NVL(:THE_MONTH,0)
                              AND CONSOLIDATION_CD =  NVL(:THE_CONSOLIDATION_CD,0)
                              AND FINANCIAL_ELEM_ID = NVL(:THE_FINANCIAL_ELEM_ID,0)
                              AND ORG_UNIT_ID   = NVL(:THE_ORG_UNIT_ID,0)
                              AND GL_ACCOUNT_ID = NVL(:THE_GL_ACCOUNT_ID,0)
                              AND COMMON_COA_ID = NVL(:THE_COMMON_COA_ID,0)
                              AND PRODUCT_1_ID  = NVL(:THE_PRODUCT_1_ID,0)
                              AND PRODUCT_ID    = NVL(:THE_PRODUCT_ID,0)
                              AND PRODUCT_3_ID  = NVL(:THE_PRODUCT_3_ID,0)
                              AND COST_TYPE_ID    = NVL(:THE_MEMO_GL_ACCOUNT_ID,0)
                              AND BALANCE_TYPE_CD = NVL(:THE_BALANCE_TYPE_CD,0)', V_DAY, V_DAY)
            USING V_AMOUNT, V_IDENTITY_CODE, V_YEAR_S, V_MONTH, V_CONSOLIDATION_CD, V_FINANCIAL_ELEM_ID, V_ORG_UNIT_ID, 
            V_GL_ACCOUNT_ID, V_COMMON_COA_ID, V_PRODUCT_1_ID, V_PRODUCT_ID, V_PRODUCT_3_ID, V_MEMO_GL_ACCOUNT_ID, V_BALANCE_TYPE_CD;

        END IF; 

    END IF;



END IN_LEDGER_STAT_DAILY;


END POST_ENTRIES ;
/

【问题讨论】:

  • 您是否在另一个会话中插入或更新了 LEDGER_STAT_DLY 中的任何数据,但未提交?您的程序中的更新可能刚刚被阻止。 (顺便说一句,第一个查询不需要是动态的;您应该使用实际日期而不是依赖隐式转换和 NLS 设置的字符串。)
  • 这里有包体,但没有规范部分。
  • @AlexPoole:我在Dailygl_test table 中插入了数据但提交了它。我已经关闭了没有结束的会话。 Could you please suggest should I just run COMMIT again to ensure issue#1, as pointed by you, is resolved. If not, what else should I do to address issue#1? Before running the proc, I've set the values of column to zero and proc has updated value for Day_31 column for May month but it never went to day_01 and day_02 column of June month ...
  • ...我尝试使用动态查询,这是我的第一次尝试。您能否通过编辑我的代码或评论我如何根据您的建议传递实际日期来告诉我?此外,根据我的理解,日期不应该是一个问题,因为我单独运行选择查询并给出了预期的结果。
  • @BarbarosÖzhan:完成。刚刚编辑了问题的代码部分。

标签: oracle plsql


【解决方案1】:

第一个过程中的循环永远不会退出;你需要添加类似的东西

                EXIT WHEN seq%NOTFOUND;

即:

...
    OPEN seq FOR V_SQL;

            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,  
                            V_AVG_BAL,  
                            V_FLAG;                                 

                EXIT WHEN seq%NOTFOUND;

                IF V_FLAG = 'Y' THEN
...

如 cmets 中所述,该过程中的游标查询不需要是动态的;并且您应该使用实际日期而不是依赖于隐式转换和 NLS 设置的字符串 - 或者至少是字符串和日期之间的显式转换。

【讨论】:

  • 谢谢。实际上,V_DATE:= USB.DLY_AOD(82);。我正在计算利用现有函数的返回日期并将其分配给 V_DATE,然后将其作为字符串传递,查询运行良好。我使用它是为了在动态查询运行时可以在控制台中看到日期的值。你会建议如下与 to_date()...
  • 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_TEST A, AL_LOOKUP B WHERE A.GL_ACCOUNT_ID = B.GL_ACCT AND A.AS_OF_DATE = to_date(V_DATE, 'dd-mon-yyyy') 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]'
  • 只要函数总是返回该格式的字符串(为什么不只返回日期?)和月份缩写的相同语言 *8-)
猜你喜欢
  • 1970-01-01
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-01
  • 1970-01-01
  • 2013-05-19
  • 2019-02-06
相关资源
最近更新 更多