J'ai le problème, c'est quand j'exécute la commande suivante dans Oracle, je rencontre l'erreur.
Truncate table mytable;
Les erreurs:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
J'ai trouvé que cette table avait une relation avec les autres tables. C'est pourquoi la commande Truncate ne peut plus continuer. Comment supprimer des données de myTable avec les scripts SQL en utilisant la commande Truncate?
Vous devez remplacer l'instruction TRUNCATE par une instruction DELETE, plus lente et journalisée, mais c'est le moyen de procéder lorsque des contraintes sont en place.
DELETE mytablename;
Vous pouvez également trouver les clés étrangères référençant la table en question et les désactiver temporairement.
select 'ALTER TABLE '||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';'
from user_constraints
where R_CONSTRAINT_NAME='<pk-of-table>';
Où pk-of-table
est le nom de la clé primaire de la table tronquée
Exécutez le résultat de la requête ci-dessus. Quand cela est fait, n'oubliez pas de les réactiver, changez simplement DISABLE CONSTRAINT
en ENABLE CONSTRAINT
cette page offre une très bonne solution ...
ORA-02266: clés uniques/primaires de la table référencées par des clés étrangères activées
Je suis en train d'en copier la solution:
en utilisant n’importe quel éditeur de texte .. changez simplement disable pour activer le résultat de la requête, puis exécutez-le.
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');
Le message d'erreur vous indique qu'il existe d'autres tables avec une contrainte de clé étrangère faisant référence à votre table.
Selon les docs Oracle
Vous ne pouvez pas tronquer la table parent d'une contrainte de clé étrangère activée . Vous devez désactiver la contrainte avant tronquer la table.
La syntaxe pour désactiver une clé étrangère est la suivante:
ALTER TABLE nom_table désactiver CONSTRAINT nom_contrainte;
Problème:
Error “ORA-02266: unique/primary keys in table referenced by enabled foreign keys” when trying to truncate a table.
Message d'erreur:
SQL> truncate table TABLE_NAME;
truncate table TABLE_NAME
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
Solution: -- Recherchez les contraintes de clé étrangère référencées.
SQL> select 'alter table '||a.owner||'.'||a.table_name||' disable constraint '||a.constraint_name||';'
2 from all_constraints a, all_constraints b
3 where a.constraint_type = 'R'
4 and a.r_constraint_name = b.constraint_name
5 and a.r_owner = b.owner
6 and b.table_name = 'TABLE_NAME';
'ALTER TABLE'||A.OWNER||'.'||A.TABLE_NAME||'DISABLE CONSTRAINT'||A.CONSTRAINT_NAME||';'
---------------------------------------------------------------------------------------------------------
alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT disable constraint CONSTRAINT_NAME;
alter table SCHEMA_NAME.TABLE_NAME_LOCATION disable constraint CONSTRAINT_NAME;
- les désactiver
alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT disable constraint CONSTRAINT_NAME;
alter table SCHEMA_NAME.TABLE_NAME_LOCATION disable constraint CONSTRAINT_NAME;
- Exécuter le tronqué
SQL> truncate table TABLE_NAME;
Table truncated.
- Activer les clés étrangères
SQL> select 'alter table '||a.owner||'.'||a.table_name||' enable constraint '||a.constraint_name||';'
2 from all_constraints a, all_constraints b
3 where a.constraint_type = 'R'
4 and a.r_constraint_name = b.constraint_name
5 and a.r_owner = b.owner
6 and b.table_name = 'TABLE_NAME';
'ALTER TABLE'||A.OWNER||'.'||A.TABLE_NAME||'ENABLE CONSTRAINT'||A.CONSTRAINT_NAME||';'
--------------------------------------------------------------------------------
alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT enable constraint CONSTRAINT_NAME;
alter table SCHEMA_NAME.TABLE_NAME_LOCATION enable constraint CONSTRAINT_NAME;
- les activer
alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT enable constraint CONSTRAINT_NAME;
alter table SCHEMA_NAME.TABLE_NAME_LOCATION enable constraint CONSTRAINT_NAME;
Oracle 12c a introduit une fonctionnalité pour tronquer une table parent d'une contrainte d'intégrité référentielle ayant la règle ON DELETE.
Au lieu de truncate table tablename;
, utilisez:
TRUNCATE TABLE tablename CASCADE;
Depuis Oracle truncate table
documentation:
Si vous spécifiez CASCADE, Oracle Database tronque toutes les tables enfant qui référencent la table avec une contrainte référentielle ON DELETE CASCADE activée. Il s’agit d’une opération récursive qui tronque toutes les tables enfants, les tables de groupe, etc., à l’aide des options spécifiées.
TRUNCATE TABLE TEST2 DROP ALL STORAGE;
Cette déclaration fonctionne réellement quand il existe une contrainte de clé étrangère appliquée à une table .table
J'ai eu le problème similaire et je l'ai trié par les scripts suivants.
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;
/
Ce script va d'abord désactiver toutes les contraintes. Tronque les données dans les tables et active ensuite les contraintes.
J'espère que ça aide.
à votre santé..
Une approche typique pour supprimer plusieurs lignes avec de nombreuses contraintes est la suivante:
mytable_new
avec toutes les colonnes mais sans contrainte (ou créer des contraintes désactivées);mytable
à mytable_new
.mytable_new
pour voir que tout va bien.mytable
en référence à mytable_new
à la place et vérifiez que tout va bien.drop table mytable
.alter table mytable_new rename to mytable
.C'est beaucoup plus rapide que de supprimer un million d'enregistrements avec de nombreuses contraintes lentes.