oracle pl/sql:在异常节中声明游标时出错

ki0zmccv  于 2023-11-17  发布在  Oracle
关注(0)|答案(4)|浏览(124)

请问这个函数有什么问题:我得到这个错误:遇到符号“CFCE”时,预期以下之一:= .(@ % ;注意:当我在声明部分声明游标没有错误,但我需要在异常部分声明它

CREATE OR REPLACE FUNCTION PMISHR.SYS_ENCASH_FC
(
    PRM_POLICY_KEY VARCHAR2,
    PRM_POLDEBTOR_SEQ NUMBER,
    PRM_SYSTEMIND VARCHAR2 DEFAULT 'G',
    PRM_AGTBDX_DATE DATE
)
   RETURN VARCHAR2 IS
   --V_FC_PREMIUM  VARCHAR2(3000 BYTE);
   V_FC_PREMIUM  CLOB :='';
   
BEGIN
    
    IF PRM_SYSTEMIND = 'G' THEN
        BEGIN
            /* AUTO RECONCILIATION */
            
        
            SELECT  AGB_COMP_REF_NO
            INTO    V_FC_PREMIUM
            FROM    CDNOTE_RECONCILE_DATA, CDNOTE, AGENTVOBRX, AGENTBORDEREAUX, GENPOLDEBTOR
            WHERE   CDR_RECONCILE_SOURCE = 'GENPOLICY'
            AND     CDR_RECONCILE_SOURCE = CDN_SOURCE_TABLE
            AND     NVL(CDR_MANUALRECONCILE_IND,'N') = 'N'
            AND     CDN_SOURCE_CDE = POL_POLICY_CDE
            AND     CDN_SOURCE_SEQ = POL_POLDEBTOR_SEQ
            AND     POL_POLICY_CDE = PRM_POLICY_KEY
            AND     POL_POLDEBTOR_SEQ = PRM_POLDEBTOR_SEQ
            AND     CDR_CDNOTE_TYPE = CDNOTE_TYPE
            AND     CDR_CDN_NUMBER_SYSTEM = CDNOTE_NUMBER
            AND     ((CDR_VO_BRX_PREM_CDN_TYPE = AVO_CDNOTE_TYPE AND AVO_CDNOTE_NUMBER = CDR_CDN_NUMBER_VO_BRX)
                      OR (CDR_CDN_NUMBER_VO_BRX IS NULL AND CDR_PREMIUMS_VO_CDE = AVO_PREMIUMSVO_CDE)
                    )
            AND     AVO_AGENTBORDEREAUX_CDE = AGENTBORDEREAUX_KEY
            AND     TRUNC(AGENTBORDEREAUX.A_DATE_TIME_CREATED) <= TRUNC(PRM_AGTBDX_DATE)
            AND     ROWNUM<=1; 
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                /* MANUAL RECONCILIATION */

                CURSOR cFCE(PRM_POLICY_KEY VARCHAR2,PRM_POLDEBTOR_SEQ NUMBER) IS
                SELECT AGB_COMP_REF_NO
                FROM    MANUALPREMIUM_RECONCILE, CDNOTE_RECONCILE_DATA, CDNOTE, AGENTVOBRX, AGENTBORDEREAUX
                WHERE   CDNOTE.CDN_SOURCE_TABLE = 'GENPOLICY'
                AND     CDNOTE.CDN_SOURCE_CDE = PRM_POLICY_KEY
                AND     CDNOTE.CDN_SOURCE_SEQ = PRM_POLDEBTOR_SEQ
                AND     CDR_CDNOTE_TYPE = CDNOTE_TYPE
                AND     CDR_CDN_NUMBER_SYSTEM = CDNOTE_NUMBER
                AND     CDR_RECONCILE_WITH = 'AGENTVOBRX'
                AND     NVL(CDR_MANUALRECONCILE_IND,'N') = 'Y'
                AND     CDR_MANUALRECONCILE_BATCH_CDE = MPR_RECONCILE_BATCH_ID
                AND     CDR_VO_BRX_PREM_CDN_TYPE = AVO_CDNOTE_TYPE
                AND     AVO_CDNOTE_NUMBER = CDR_CDN_NUMBER_VO_BRX
                AND     AVO_AGENTBORDEREAUX_CDE = AGENTBORDEREAUX_KEY
                AND     MPR_CDNOTE_TYPE = CDR_CDNOTE_TYPE
                AND     MPR_CDNOTE_NUMBER = CDR_CDN_NUMBER_SYSTEM
                AND     TRUNC(AGENTBORDEREAUX.A_DATE_TIME_CREATED) <= TRUNC(PRM_AGTBDX_DATE)
                AND     AGB_VALID_IND = 'Y'
;   
rFCE cFCE%ROWTYPE; 
                 OPEN cFCE(PRM_POLICY_KEY,PRM_POLDEBTOR_SEQ);
                 LOOP
                    FETCH cFCE INTO rFCE;
                    EXIT WHEN cFCE%NOTFOUND;
                    V_FC_PREMIUM := V_FC_PREMIUM || rFCE.AGB_COMP_REF_NO || ' ; ';
                 END LOOP;
                 CLOSE cFCE;
                 
                 if length(V_FC_PREMIUM)>4000 then V_FC_PREMIUM:= substr(V_FC_PREMIUM,1,4000); end if;
                 
            END; 
        RETURN V_FC_PREMIUM;

    ELSE
        BEGIN
            /* AUTO RECONCILIATION */
            SELECT  AGB_COMP_REF_NO
            INTO    V_FC_PREMIUM
            FROM    CDNOTE_RECONCILE_DATA, CDNOTE, AGENTVOBRX, AGENTBORDEREAUX, LIFEPOLDEBTOR
            WHERE   CDR_RECONCILE_SOURCE = 'LIFE_POLICY'
            AND     CDR_RECONCILE_SOURCE = CDN_SOURCE_TABLE
            AND     NVL(CDR_MANUALRECONCILE_IND,'N') = 'N'
            AND     CDN_SOURCE_CDE = POL_POLICY_CDE
            AND     CDN_SOURCE_SEQ = POL_POLDEBTOR_SEQ
            AND     POL_POLICY_CDE = PRM_POLICY_KEY
            AND     POL_POLDEBTOR_SEQ = PRM_POLDEBTOR_SEQ
            AND     CDR_CDNOTE_TYPE = CDNOTE_TYPE
            AND     CDR_CDN_NUMBER_SYSTEM = CDNOTE_NUMBER
            AND     CDR_VO_BRX_PREM_CDN_TYPE = AVO_CDNOTE_TYPE
            AND     AVO_CDNOTE_NUMBER = CDR_CDN_NUMBER_VO_BRX
            AND     AVO_AGENTBORDEREAUX_CDE = AGENTBORDEREAUX_KEY
            AND     TRUNC(AGENTBORDEREAUX.A_DATE_TIME_CREATED) <= TRUNC(PRM_AGTBDX_DATE)
            AND     ROWNUM<=1; 
        EXCEPTION
            WHEN NO_DATA_FOUND THEN   
                /* MANUAL RECONCILIATION */
                SELECT  AGB_COMP_REF_NO 
                INTO    V_FC_PREMIUM
                FROM    MANUALPREMIUM_RECONCILE, CDNOTE_RECONCILE_DATA, CDNOTE, AGENTVOBRX, AGENTBORDEREAUX
                WHERE   CDNOTE.CDN_SOURCE_TABLE = 'LIFE_POLICY'
                AND     CDNOTE.CDN_SOURCE_CDE = PRM_POLICY_KEY
                AND     CDNOTE.CDN_SOURCE_SEQ = PRM_POLDEBTOR_SEQ
                AND     CDR_CDNOTE_TYPE = CDNOTE_TYPE
                AND     CDR_CDN_NUMBER_SYSTEM = CDNOTE_NUMBER
                AND     CDR_RECONCILE_WITH = 'AGENTVOBRX'
                AND     NVL(CDR_MANUALRECONCILE_IND,'N') = 'Y'
                AND     CDR_MANUALRECONCILE_BATCH_CDE = MPR_RECONCILE_BATCH_ID
                AND     CDR_VO_BRX_PREM_CDN_TYPE = AVO_CDNOTE_TYPE
                AND     AVO_CDNOTE_NUMBER = CDR_CDN_NUMBER_VO_BRX
                AND     AVO_AGENTBORDEREAUX_CDE = AGENTBORDEREAUX_KEY
                AND     MPR_CDNOTE_TYPE = CDR_CDNOTE_TYPE
                AND     MPR_CDNOTE_NUMBER = CDR_CDN_NUMBER_SYSTEM
                AND     TRUNC(AGENTBORDEREAUX.A_DATE_TIME_CREATED) <= TRUNC(PRM_AGTBDX_DATE)
                AND     AGB_VALID_IND = 'Y'
                AND     ROWNUM<=1;
            END; 
        RETURN V_FC_PREMIUM;
    END IF;
    
END;
/

字符串
我有这个错误
遇到符号“CFCE”时,预期以下之一:= .(@ % ;注意:当我在第一节中声明游标时,没有问题,但由于性能问题,我需要在异常节中声明它

dbf7pr2w

dbf7pr2w1#

通过阅读评论,我发现您找到了一个解决方法(listagg函数;注意,如果结果字符串超过4000个字符,它将无法工作)。
至于另一个评论/回答说,你不能在异常处理部分声明游标-好吧,这是不正确的。你可以,但你必须以支持的方式来做,通过包括declare关键字。
下面是一个例子;请参阅代码中的注解。

SQL> create or replace function f_test return varchar2
  2  is
  3    l_val  number;
  4    retval varchar2(10);
  5  begin
  6    retval := 'X';      
  7    -- this will raise ZERO_DIVIDE error
  8    l_val := 1 / 0;
  9    return retval;  --> function would return 'X', if there weren't for an error
 10
 11  exception
 12    when zero_divide then
 13      declare                 --> this is DECLARE you need
 14        cursor c1 is select dname from dept where rownum = 1;
 15        c1r c1%rowtype;
 16      begin
 17        open c1;
 18        fetch c1 into retval;
 19        close c1;
 20        return retval;
 21      end;
 22  end;
 23  /

Function created.

SQL> select f_test from dual;

F_TEST
--------------------------------------------------------------------------------
ACCOUNTING

SQL>

字符串

nsc4cvqm

nsc4cvqm2#

不允许在异常节中声明游标。您可以尝试在声明节中声明游标,然后通过在异常节中获取来使用它。

mpgws1up

mpgws1up3#

如果你要使用CURSOR,那么它需要在PL/SQL块的DECLARE部分:

(
    PRM_POLICY_KEY VARCHAR2,
    PRM_POLDEBTOR_SEQ NUMBER,
    PRM_SYSTEMIND VARCHAR2 DEFAULT 'G',
    PRM_AGTBDX_DATE DATE
) RETURN VARCHAR2
IS
  V_FC_PREMIUM  VARCHAR2(4000 BYTE);
  V_FC_PREMIUM  CLOB :='';  
BEGIN
  IF PRM_SYSTEMIND = 'G' THEN
    BEGIN
      /* AUTO RECONCILIATION */
      SELECT  AGB_COMP_REF_NO
      INTO    V_FC_PREMIUM
      FROM    CDNOTE_RECONCILE_DATA, CDNOTE, AGENTVOBRX, AGENTBORDEREAUX, GENPOLDEBTOR
      WHERE   CDR_RECONCILE_SOURCE = 'GENPOLICY'
      AND     CDR_RECONCILE_SOURCE = CDN_SOURCE_TABLE
      AND     NVL(CDR_MANUALRECONCILE_IND,'N') = 'N'
      AND     CDN_SOURCE_CDE = POL_POLICY_CDE
      AND     CDN_SOURCE_SEQ = POL_POLDEBTOR_SEQ
      AND     POL_POLICY_CDE = PRM_POLICY_KEY
      AND     POL_POLDEBTOR_SEQ = PRM_POLDEBTOR_SEQ
      AND     CDR_CDNOTE_TYPE = CDNOTE_TYPE
      AND     CDR_CDN_NUMBER_SYSTEM = CDNOTE_NUMBER
      AND     ((CDR_VO_BRX_PREM_CDN_TYPE = AVO_CDNOTE_TYPE AND AVO_CDNOTE_NUMBER = CDR_CDN_NUMBER_VO_BRX)
                OR (CDR_CDN_NUMBER_VO_BRX IS NULL AND CDR_PREMIUMS_VO_CDE = AVO_PREMIUMSVO_CDE)
              )
      AND     AVO_AGENTBORDEREAUX_CDE = AGENTBORDEREAUX_KEY
      AND     TRUNC(AGENTBORDEREAUX.A_DATE_TIME_CREATED) <= TRUNC(PRM_AGTBDX_DATE)
      AND     ROWNUM<=1; 
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        /* MANUAL RECONCILIATION */
        DECLARE
          CURSOR cFCE(PRM_POLICY_KEY VARCHAR2,PRM_POLDEBTOR_SEQ NUMBER) IS
          SELECT AGB_COMP_REF_NO
          FROM    MANUALPREMIUM_RECONCILE, CDNOTE_RECONCILE_DATA, CDNOTE, AGENTVOBRX, AGENTBORDEREAUX
          WHERE   CDNOTE.CDN_SOURCE_TABLE = 'GENPOLICY'
          AND     CDNOTE.CDN_SOURCE_CDE = PRM_POLICY_KEY
          AND     CDNOTE.CDN_SOURCE_SEQ = PRM_POLDEBTOR_SEQ
          AND     CDR_CDNOTE_TYPE = CDNOTE_TYPE
          AND     CDR_CDN_NUMBER_SYSTEM = CDNOTE_NUMBER
          AND     CDR_RECONCILE_WITH = 'AGENTVOBRX'
          AND     NVL(CDR_MANUALRECONCILE_IND,'N') = 'Y'
          AND     CDR_MANUALRECONCILE_BATCH_CDE = MPR_RECONCILE_BATCH_ID
          AND     CDR_VO_BRX_PREM_CDN_TYPE = AVO_CDNOTE_TYPE
          AND     AVO_CDNOTE_NUMBER = CDR_CDN_NUMBER_VO_BRX
          AND     AVO_AGENTBORDEREAUX_CDE = AGENTBORDEREAUX_KEY
          AND     MPR_CDNOTE_TYPE = CDR_CDNOTE_TYPE
          AND     MPR_CDNOTE_NUMBER = CDR_CDN_NUMBER_SYSTEM
          AND     TRUNC(AGENTBORDEREAUX.A_DATE_TIME_CREATED) <= TRUNC(PRM_AGTBDX_DATE)
          AND     AGB_VALID_IND = 'Y';   

          rFCE cFCE%ROWTYPE; 
        BEGIN
          OPEN cFCE(PRM_POLICY_KEY,PRM_POLDEBTOR_SEQ);
          LOOP
            FETCH cFCE INTO rFCE;
            EXIT WHEN cFCE%NOTFOUND;
            EXIT WHEN LENGTH(V_FC_PREMIUM) + LENGTH(rFCE.AGB_COMP_REF_NO) + 3 > 4000;
            IF V_FC_PREMIUM IS NULL THEN
              V_FC_PREMIUM := rFCE.AGB_COMP_REF_NO;
            ELSE
              V_FC_PREMIUM := V_FC_PREMIUM || ' ; ' || rFCE.AGB_COMP_REF_NO;
            END IF;
          END LOOP;
          CLOSE cFCE;
        END; 
    END; 
    RETURN V_FC_PREMIUM;
  ELSE
    BEGIN
      /* AUTO RECONCILIATION */
      SELECT  AGB_COMP_REF_NO
      INTO    V_FC_PREMIUM
      FROM    CDNOTE_RECONCILE_DATA, CDNOTE, AGENTVOBRX, AGENTBORDEREAUX, LIFEPOLDEBTOR
      WHERE   CDR_RECONCILE_SOURCE = 'LIFE_POLICY'
      AND     CDR_RECONCILE_SOURCE = CDN_SOURCE_TABLE
      AND     NVL(CDR_MANUALRECONCILE_IND,'N') = 'N'
      AND     CDN_SOURCE_CDE = POL_POLICY_CDE
      AND     CDN_SOURCE_SEQ = POL_POLDEBTOR_SEQ
      AND     POL_POLICY_CDE = PRM_POLICY_KEY
      AND     POL_POLDEBTOR_SEQ = PRM_POLDEBTOR_SEQ
      AND     CDR_CDNOTE_TYPE = CDNOTE_TYPE
      AND     CDR_CDN_NUMBER_SYSTEM = CDNOTE_NUMBER
      AND     CDR_VO_BRX_PREM_CDN_TYPE = AVO_CDNOTE_TYPE
      AND     AVO_CDNOTE_NUMBER = CDR_CDN_NUMBER_VO_BRX
      AND     AVO_AGENTBORDEREAUX_CDE = AGENTBORDEREAUX_KEY
      AND     TRUNC(AGENTBORDEREAUX.A_DATE_TIME_CREATED) <= TRUNC(PRM_AGTBDX_DATE)
      AND     ROWNUM<=1; 
    EXCEPTION
      WHEN NO_DATA_FOUND THEN   
        /* MANUAL RECONCILIATION */
        SELECT  AGB_COMP_REF_NO 
        INTO    V_FC_PREMIUM
        FROM    MANUALPREMIUM_RECONCILE, CDNOTE_RECONCILE_DATA, CDNOTE, AGENTVOBRX, AGENTBORDEREAUX
        WHERE   CDNOTE.CDN_SOURCE_TABLE = 'LIFE_POLICY'
        AND     CDNOTE.CDN_SOURCE_CDE = PRM_POLICY_KEY
        AND     CDNOTE.CDN_SOURCE_SEQ = PRM_POLDEBTOR_SEQ
        AND     CDR_CDNOTE_TYPE = CDNOTE_TYPE
        AND     CDR_CDN_NUMBER_SYSTEM = CDNOTE_NUMBER
        AND     CDR_RECONCILE_WITH = 'AGENTVOBRX'
        AND     NVL(CDR_MANUALRECONCILE_IND,'N') = 'Y'
        AND     CDR_MANUALRECONCILE_BATCH_CDE = MPR_RECONCILE_BATCH_ID
        AND     CDR_VO_BRX_PREM_CDN_TYPE = AVO_CDNOTE_TYPE
        AND     AVO_CDNOTE_NUMBER = CDR_CDN_NUMBER_VO_BRX
        AND     AVO_AGENTBORDEREAUX_CDE = AGENTBORDEREAUX_KEY
        AND     MPR_CDNOTE_TYPE = CDR_CDNOTE_TYPE
        AND     MPR_CDNOTE_NUMBER = CDR_CDN_NUMBER_SYSTEM
        AND     TRUNC(AGENTBORDEREAUX.A_DATE_TIME_CREATED) <= TRUNC(PRM_AGTBDX_DATE)
        AND     AGB_VALID_IND = 'Y'
        AND     ROWNUM<=1;
    END; 
    RETURN V_FC_PREMIUM;
  END IF;
END;
/

字符串

  • 注意:这是未经测试的,因为我们没有访问您的表。
  • 注二:如果你能以一种一致的方式修改你的代码,这会很有帮助;否则它会变得很难阅读,你也不能很容易地分辨出你在遵循程序的哪个分支。
  • 注三:你尝试连接字符串,然后检查它是否超过4000字节;这永远不会发生,因为当你尝试连接时,它超过4000字节,然后会引发异常,你永远不会到达检查条件。相反,先检查,然后再连接。*
blmhpbnm

blmhpbnm4#

谢谢你们的回答。我用了函数LISTAGG,它解决了我的问题

相关问题