Вставка массовых записей в удаленную базу данных (dblink) с помощью Bulk Collect
Я хочу вставить огромные записи из разных таблиц в целевую удаленную таблицу Audition_Detail, используя DBLINK - @FMATLINK. Я использовал Bulk собирать, но его бросать ошибки. Я тоже просмотрел несколько ссылок:
Преодоление ограничения на массовые вставки по ссылке в базе данных
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: неверное количество значений в списке INTO оператора FETCH
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 ответ
Сообщение об ошибке кажется достаточно ясным:
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'
Легче понять, легко обнаружить недостающее соединение. Читаемость это особенность.