使用批量收集将批量记录插入到远程数据库(dblink)中

时间:2019-02-09 08:52:55

标签: oracle plsql oracle-sqldeveloper forall bulk-collect

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

Overcoming the restriction on bulk inserts over a database link

PLS-00394: Wrong number of values in the INTO list of a fetch statement

代码如下:

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:远程表不支持FORALL INSERT / UPDATE / DELETE   06550. 00000-“%s行,%s列:\ n%s”

     

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

1 个答案:

答案 0 :(得分:3)

错误消息似乎足够清楚:

  

在远程表上不支持的全部插入/更新/删除操作。

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

幸运的是,您无需在代码中使用批量收集和FORALL。一个简单的INSERT INTO .... SELECT语句应该可以正确显示:

from  scipy.stats import zscore

df['s_z'] = df.groupby('G')['S'].transform(lambda x: (x-x.mean())/x.std())
df['s_z1'] = df.groupby('G')['S'].transform(lambda x: zscore(x, ddof=1))
print (df)
    G         S       s_z      s_z1
0   B  0.444939 -0.630865 -0.630865
1   D  0.407554 -0.707107 -0.707107
2   C  0.460148 -1.397499 -1.397499
3   B  0.465239 -0.522127 -0.522127
4   A  0.462691  0.707107  0.707107
5   A  0.016545 -0.707107 -0.707107
6   D  0.850445  0.707107  0.707107
7   C  0.817744  0.371317  0.371317
8   B  0.777962  1.152993  1.152993
9   C  0.757983  0.075715  0.075715
10  C  0.934829  0.950467  0.950467

您的代码没有使用显式的ANSI 92连接语法,并且您已经压缩了代码,因此很难阅读。因此,很容易遗漏尚未为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' 编写连接条件。因此,两个子查询都将为APPS.HZ_LOCATIONS@FMATLINK C中的所有记录生成笛卡尔乘积。您可能不想要这个。

C

更易于理解,易于发现缺失的联接。可读性是一个功能。