Сократить таблицу в Oracle, получив ошибки
У меня возникла проблема, когда я запускаю следующую команду в Oracle, я столкнулся с этой ошибкой.
Truncate table mytable;
Ошибка:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
Я обнаружил, что эта таблица имеет отношения с другими таблицами. Вот почему команда Truncate больше не может работать. Как удалить данные из myTable с помощью сценариев SQL с помощью команды Truncate?
Ответы
Ответ 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