2

我想使用 DBLINK - @FMATLINK 将来自不同表的大量记录插入目标远程表“Audition_Detail”。我使用了批量收集,但它的抛出错误。我也浏览了一些链接:

克服通过数据库链接进行批量插入的限制

PLS-00394:提取语句的 INTO 列表中的值数量错误

代码如下:

DECLARE
    TYPE FETCH_ARRAY IS TABLE OF AUDITION_DETAIL@FMATLINK%ROWTYPE;   
    A_DATA FETCH_ARRAY;

    CURSOR A_CUR IS
        --------------------------------------------------------Address1--------------------------------------------------------------------------

        SELECT A.PARTY_SITE_NUMBER FMAT_FMATID, B.ZADDRESSFMATID F4F_FMATID,
        C.ADDRESS1 FMAT_VALUE, B.STREET F4F_VALUE , 'ADDRESS1' 
        FROM APPS.HZ_PARTY_SITES@FMATLINK A , f4f_corporateaccount B , APPS.HZ_LOCATIONS@FMATLINK C
        WHERE 1=1
        AND B.ROLECODETEXT = 'Site Account'
        AND A.PARTY_SITE_NUMBER = B.ZADDRESSFMATID
        AND A.STATUS = 'A'

        UNION ALL 
        ------------------------------------------------------Address2-----------------------------------------------------------------------------

        SELECT A.PARTY_SITE_NUMBER FMAT_FMATID, B.ZADDRESSFMATID F4F_FMATID,
        C.ADDRESS2 FMAT_VALUE, B.addressline1 F4F_VALUE , 'ADDRESS2'  
        FROM APPS.HZ_PARTY_SITES@FMATLINK A , f4f_corporateaccount B , APPS.HZ_LOCATIONS@FMATLINK C
        WHERE 1=1
        AND B.ROLECODETEXT = 'Site Account'
        AND A.PARTY_SITE_NUMBER = B.ZADDRESSFMATID
        AND A.STATUS = 'A'


BEGIN   
    OPEN A_CUR;
    LOOP                      
        FETCH A_CUR BULK COLLECT INTO A_DATA LIMIT 20; 
            FORALL IN 1..A_DATA.COUNT     
            INSERT INTO AUDITION_DETAIL@FMATLINK VALUES A_DATA(i);

        EXIT WHEN A_CUR%NOTFOUND;
    END LOOP;
    CLOSE A_CUR;
    COMMIT;
END;

错误报告 -

ORA-06550:第 39 行,第 3 列:

PLS-00394:FETCH 语句的 INTO 列表中的值数量错误

ORA-06550:第 39 行,第 3 列:

PL/SQL:忽略 SQL 语句

ORA-06550:第 40 行,第 4 列:

PLS-00739:远程表 06550 不支持 FORALL INSERT/UPDATE/DELETE。00000 -“行 %s,列 %s:\n%s”

*原因:通常是 PL/SQL 编译错误。*行动:

4

1 回答 1

3

错误消息似乎很清楚:

远程表不支持FORALL INSERT/UPDATE/DELETE 。

实际上,您链接到另一个问题,该问题解释了这是一个实施限制。PL/SQL 不允许我们跨数据库链接使用 FORALL 语句,就是这样。

幸运的是,您不需要在代码中使用批量收集和 FORALL。一个简单的 INSERT INTO .... SELECT 语句应该可以看到:

INSERT INTO AUDITION_DETAIL@FMATLINK 
    SELECT A.PARTY_SITE_NUMBER FMAT_FMATID, B.ZADDRESSFMATID F4F_FMATID,
    C.ADDRESS1 FMAT_VALUE, B.STREET F4F_VALUE , 'ADDRESS1' 
    FROM APPS.HZ_PARTY_SITES@FMATLINK A , f4f_corporateaccount B , APPS.HZ_LOCATIONS@FMATLINK C
    WHERE 1=1
    AND B.ROLECODETEXT = 'Site Account'
    AND A.PARTY_SITE_NUMBER = B.ZADDRESSFMATID
    AND A.STATUS = 'A'

    UNION ALL 
    ------------------------------------------------------Address2-----------------------------------------------------------------------------

    SELECT A.PARTY_SITE_NUMBER FMAT_FMATID, B.ZADDRESSFMATID F4F_FMATID,
    C.ADDRESS2 FMAT_VALUE, B.addressline1 F4F_VALUE , 'ADDRESS2'  
    FROM APPS.HZ_PARTY_SITES@FMATLINK A , f4f_corporateaccount B , APPS.HZ_LOCATIONS@FMATLINK C
    WHERE 1=1
    AND B.ROLECODETEXT = 'Site Account'
    AND A.PARTY_SITE_NUMBER = B.ZADDRESSFMATID
    AND A.STATUS = 'A'

您的代码没有使用显式的 ANSI 92 连接语法,并且您已经对代码进行了整理,因此很难阅读。因此很容易错过您没有为APPS.HZ_LOCATIONS@FMATLINK C. 因此,两个子查询都会为 中的所有记录生成笛卡尔积C。你可能不想要这个。

SELECT A.PARTY_SITE_NUMBER as FMAT_FMATID
        , B.ZADDRESSFMATID as F4F_FMATID
        , C.ADDRESS2 as FMAT_VALUE
        , B.addressline1 as F4F_VALUE
        , 'ADDRESS2'  
FROM APPS.HZ_PARTY_SITES@FMATLINK A
      inner join  f4f_corporateaccount B on A.PARTY_SITE_NUMBER = B.ZADDRESSFMATID
      inner join  APPS.HZ_LOCATIONS@FMATLINK C on ** something goes here **
WHERE  B.ROLECODETEXT = 'Site Account'
AND A.STATUS = 'A'

更容易理解,容易发现缺失的连接。可读性是一个特点。

于 2019-02-09T09:23:05.887 回答