Не удается обновить столбец из объединения - PullRequest
0 голосов
/ 01 апреля 2020

Я хочу обновить столбец в таблице 2 данными из столбца в таблице 1 на основе сравнения другого столбца в таблице 2 и таблице 1.

Пример.

enter image description here

Я использовал этот скрипт:

DECLARE

    TYPE dataRows_t IS TABLE OF table1.tagid%TYPE
    INDEX BY PLS_INTEGER;
    Tag   dataRows_t;
    tempTag dataRows_t;

BEGIN

    SELECT t1.tagid, t1.tagidB
    BULK COLLECT INTO Tag, tempTag
    FROM table1 t1;

    FORALL indx IN 1 .. Tag.COUNT
        UPDATE table2 t2
        SET t2.tagid = tag(indx)
        WHERE t2.tempTagIdB = temptag(indx);
    COMMIT;
END;

, который работает нормально до 40 тыс. Строк (около 3 минут до завершения)

Моя следующая попытка на 60 тыс. Не закончилась через 10 минут.

Я пробовал всего 89 тыс. Строк за 9 часов и не завершил.

Однако, когда я отменил сценарий, я увидел, что значения были обновлены должным образом, но сценарий еще не завершен.

Я знаю, что проверка условия на 89 тыс. строк, вероятно, не самая эффективная, но я не нашел лучшего решения и предположил, что оно завершится в Менее одного часа.

Чего мне не хватает?

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Вместо этого я бы попробовал MERGE:

MERGE INTO table2 t2
USING (SELECT tagid, tagidB from table1) t1
ON t2.tagidB = t1.tagidB
WHEN MATCHED THEN UPDATE SET
  t2.tagid = t1.tagid

Относительно вашего комментария "когда я отменил скрипт, я мог видеть, что значения были обновлены правильно, но скрипт не завершился.". Когда вы запускаете блок кода PL / SQL, весь блок отправляется на сервер БД и там выполняется. Если вы отменяете операцию в своей клиентской программе, это не отменяет выполнение блока кода в базе данных. Ваши наблюдения показывают, что в конце концов он завершил выполнение и изменения были зафиксированы (так как ваш блок кода включает в себя принятие) Если у вас не было фиксации в блоке PL / SQL, он был бы откатан после завершения, когда обнаружил, что сеанс клиента завершился.

0 голосов
/ 01 апреля 2020

Вы можете использовать коррелированные подзапросы вместо al oop. Это должно работать в Oracle (при условии отсутствия дубликата tagIdB в table1):

update table2 t2
set t2.tagid = (select t1.tagid from table1 where t1.tagIdB = t2.tempTagIdB) 
where exists(select 1 from table1 where t1.tagIdB = t2.tempTagIdB) 
...