Подтвердить что ты не робот

Сократить таблицу в Oracle, получив ошибки

У меня возникла проблема, когда я запускаю следующую команду в Oracle, я столкнулся с этой ошибкой.

Truncate table mytable;

Ошибка:

ORA-02266: unique/primary keys in table referenced by enabled foreign keys

Я обнаружил, что эта таблица имеет отношения с другими таблицами. Вот почему команда Truncate больше не может работать. Как удалить данные из myTable с помощью сценариев SQL с помощью команды Truncate?

4b9b3361

Ответ 1

Вам нужно поменять инструкцию TRUNCATE на инструкции DELETE, замедлить и занести в журнал, но это способ сделать это, когда существуют ограничения.

DELETE mytablename;

Либо это, либо вы можете найти внешние ключи, ссылающиеся на рассматриваемую таблицу, и временно отключить их.

select 'ALTER TABLE '||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';'
from user_constraints
where R_CONSTRAINT_NAME='<pk-of-table>';

Где pk-of-table - это имя первичного ключа усеченной таблицы

Запустите вывод вышеуказанного запроса. Когда это будет сделано, не забудьте снова включить их, просто измените DISABLE CONSTRAINT на ENABLE CONSTRAINT

Ответ 2

Сообщение об ошибке сообщает вам, что есть другие таблицы (таблицы) с ограничением внешнего ключа, ссылающиеся на вашу таблицу.

В соответствии с Oracle docs

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

Синтаксис для отключения внешнего ключа:

ALTER TABLE имя_таблицы отключить CONSTRAINT constraint_name;

Ответ 3

Эта страница предлагает очень хорошее решение...

ORA-02266: уникальные/первичные ключи в таблице, на которые ссылаются активированные внешние ключи

Я вот копирую из него Решение:

  • Найдите ограничения внешних ключей ENABLED и отключите их.
  • обрезать/удалить из таблицы.
  • с помощью любого текстового редактора.. просто измените значение disable для включения в выводе, которое вы получаете из запроса, затем запустите его.

    select 'alter table '||a.owner||'.'||a.table_name||' disable constraint '||a.constraint_name||';'
    from all_constraints a, all_constraints b
    where a.constraint_type = 'R' and a.status='ENABLED'
    and a.r_constraint_name = b.constraint_name
    and a.r_owner  = b.owner
    and b.table_name = upper('YOUR_TABLE');
    

Ответ 4

Oracle 12c внедрил функцию для обрезания таблицы, являющейся родителем ограничения ссылочной целостности, имеющего правило ON DELETE.

Вместо truncate table tablename; используйте:

TRUNCATE TABLE tablename CASCADE;

Из Oracle truncate table документация:

Если вы укажете CASCADE, то Oracle Database усекает все дочерние таблицы, которые ссылаются на таблицу с включенным ссылочным ограничением ON DELETE CASCADE. Это рекурсивная операция, которая усекает все дочерние таблицы, таблицы granchild и т.д., Используя указанные параметры.

Ответ 5

Типичный подход для удаления многих строк со многими ограничениями выглядит следующим образом:

  • создать mytable_new со всеми столбцами, но без ограничений (или создать ограничения отключены);
  • скопируйте любые данные, которые вам нужны, от mytable до mytable_new.
  • включить ограничения на mytable_new, чтобы убедиться, что все в порядке.
  • изменить любые ограничения, которые ссылаются на mytable на ссылку mytable_new, и посмотреть, что все в порядке.
  • drop table mytable.
  • alter table mytable_new rename to mytable.

Это намного быстрее, чем удаление миллиона записей со многими медленными ограничениями.

Ответ 6

У меня была аналогичная проблема, и я отсортировал ее по следующим сценариям.

begin
for i in (select constraint_name, table_name from user_constraints a where a.owner='OWNER' and a.table_name not in
(select b.table_name from user_constraints b where b.table_name like '%BIN%') 
  and  a.constraint_type not in 'P')
LOOP
  execute immediate 'alter table '||i.table_name||' disable constraint '||i.constraint_name||'';
end loop;
end;
/

truncate table TABLE_1;
truncate table TABLE_2;


begin
for i in (select constraint_name, table_name from user_constraints a where a.owner='OWNER' and a.table_name not in
(select b.table_name from user_constraints b where b.table_name like '%BIN%') 
  and  a.constraint_type not in 'P')
LOOP
  execute immediate 'alter table '||i.table_name||' enable constraint '||i.constraint_name||'';
end loop;
end;
/

Этот script сначала отключит все ограничения. Усекает данные в таблицах, а затем разрешает контуры.

Надеюсь, что это поможет.

приветствия..

Ответ 7

TRUNCATE TABLE TEST2 DROP ALL STORAGE;

Этот оператор На самом деле работает, когда есть ограничение внешнего ключа, применяемое к .table

Ответ 8

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

Ссылка: Разница между командами TRUNCATE, DELETE и DROP