2017-05-24 3 views
0

Est-il possible d'ajouter ON DELETE CASCADE à une clé étrangère utilisée comme clé de partitionnement lorsqu'elle est utilisée avec PARTITION BY REFERENCE? Je parle d'une table déjà existante.Oracle: ajouter ON DELETE CASCADE à la clé étrangère utilisée dans la partition par référence

Ma solution serait de supprimer la contrainte et de la recréer, mais cela ne fonctionne pas, car je ne peux pas supprimer une contrainte utilisée par PARTITION BY REFERENCE.

Je reçois erreur SQL: ORA-14650: opération non pris en charge pour les tables partitionnées référence-

Oracle 11g.

drop table y; 
drop table x; 
create table x (a number primary key) partition by hash (a); 
create table y (a number not null, 
    constraint y_x_fk foreign key(a) references x(a)) 
    partition by reference(y_x_fk); 
alter table y drop constraint y_x_fk; 
+0

Quelque chose que je ne reçois pas: vous voulez changer la contrainte y_x_fk à supprimer en cascade? Et vous dites que vous ne pouvez pas le supprimer? Vous êtes sûr? –

+0

Oui, je reçois ORA-14650 en essayant de supprimer la contrainte. La table est partitionnée par référence et ce FK est la clé de partition et vous ne pouvez pas simplement laisser tomber une telle contrainte. – rattaman

Répondre

0

Je crois qu'il n'y a pas d'option dans ALTER...MODIFY à une option en ligne pour faire la cascade contrainte existante; Je pense que vous devrez en effet laisser tomber et recréer, ou équivalent. Je suis également d'accord, il semble qu'il n'y ait pas de moyen propre de supprimer et de recréer une contrainte de référence de partition; Je crois que vous serez confronté à une redéfinition pour y arriver.

Pour aggraver les choses, il semble que les améliorations DBMS_REFEFINITION disponibles dans 12c ne vous y obtenir dans un joli REDEF une étape, comme DBMS_REDEFINITIONdoesn't support partition de référence.

Je pense que vous aurez besoin de faire un redef old-school. (Il pourrait encore être utile d'essayer quelques DBMS_REDEFINITION avec un remplacement fait à la main, mais je serais prêt pour au moins un peu de temps d'arrêt).

Une approche similaire à l'exemple ci-dessous pourrait vous permettre d'y arriver (avec temps d'arrêt). En fonction de vos besoins de disponibilité, d'autres approches pourraient minimiser les temps d'arrêt dans cet exemple.

Faire une table de remplacement avec le choix CASCADING FK:

create table y_temp (a number not null, 
    constraint y_temp_x_fk foreign key(a) references x(a) ON DELETE CASCADE) 
partition by reference(y_temp_x_fk); 

Ensuite, allez en lecture seule:

ALTER TABLE X READ ONLY; 
ALTER TABLE Y READ ONLY; 

Synchronisez ensuite Y et Y_TEMP:

INSERT INTO Y_TEMP SELECT Y.A FROM Y; 
COMMIT; 

ensuite faire l'échange :

ALTER TABLE Y RENAME TO Y_OLD; 
ALTER TABLE Y_TEMP RENAME TO Y; 
DROP TABLE Y_OLD; 
ALTER TABLE Y RENAME CONSTRAINT y_temp_x_fk TO y_x_fk; 

Et remettre les choses pour WRITE

ALTER TABLE X READ WRITE; 

Puis le tester:

INSERT INTO X VALUES (1); 
INSERT INTO Y VALUES (1); 

SELECT * FROM Y; 

A 
1 

DELETE FROM X; 

1 row deleted. 

Et la cascade:

SELECT * FROM Y; 

no rows selected