Oracle DDL в автономной транзакции

Я должен выполнить набор (до ~1000000) sql операторы на базе данных Oracle. Эти операторы должны привести к соотносимо согласованное состояние в конце, и все операторы должны откатываться, если ошибка происходит. Эти операторы не существуют справочного порядка. Таким образом, если бы ограничения внешнего ключа включены, один из операторов может вызвать нарушение внешнего ключа даже при том, что, это нарушение было бы зафиксировано с оператором, который будет выполняться позже.

Я пытался отключить внешние ключи сначала и включить им после того, как все операторы выполнялись. Я думал, что смогу откатывать, когда было фактическое нарушение внешнего ключа. Я был неправ, хотя, я узнал, что каждый оператор DDL в Oracle, запущенной с фиксации, таким образом, не было никакого способа откатывать операторы этот путь. Вот мой сценарий для отключения внешних ключей:

begin 
  for i in (select constraint_name, table_name from user_constraints
            where constraint_type ='R' and status = 'ENABLED') 
    LOOP execute immediate 'alter table '||i.table_name||' disable constraint 
                           '||i.constraint_name||''; 
  end loop;
end;

После некоторого исследования я узнал, что рекомендовалось выполнить операторы DDL, как в этом случае, в автономной транзакции. Таким образом, я пытался выполнить операторы DDL в автономной транзакции. Это привело к следующей ошибке:

РТЫ 00054: занятый ресурс и получает с указанным NOWAIT

Я предполагаю, что это вызвано тем, что основная транзакция все еще имеет DDL, соединяют таблицы.

Я делаю что-то не так здесь или являюсь там каким-либо другим способом заставить этот сценарий работать?

7
задан OMG Ponies 25 April 2011 в 16:12
поделиться

1 ответ

Есть несколько возможных подходов.

Первое, что следует учитывать, это то, что все, что вы делаете на уровне таблицы, будет применяться ко всем сеансам, использующим эту таблицу. Если у вас нет монопольного доступа к этой таблице, вы, вероятно, не захотите удалять / воссоздавать ограничения или отключать / включать их.

Второе, что следует учитывать, это то, что вы, вероятно, не хотите откатывать миллион вставок / обновлений. Откат может быть МЕДЛЕННЫМ.

Обычно я загружаю во временную таблицу. Затем выполните один INSERT из временной таблицы в целевую таблицу. Oracle применит в конце все проверочные ограничения одним оператором.

Если вы не можете просмотреть временную таблицу (например, обновить существующие данные), перед запуском сделайте ограничения отложенными изначально немедленно . Затем в рамках сеанса

SET CONSTRAINTS emp_job_nn, emp_salary_min DEFERRED;

вы можете применить изменения, и при фиксации ограничения будут проверены.

Вам следует ознакомиться с протоколом ошибок DML , поскольку он может помочь идентифицировать любые строки, вызывающие нарушения.

8
ответ дан 7 December 2019 в 05:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: