176 votes

Comment ajouter 'ON DELETE CASCADE' dans l'instruction ALTER TABLE ?

J'ai une contrainte de clé étrangère dans ma table, je veux y ajouter ON DELETE CASCADE.

J'ai essayé :

alter table child\_table\_name
  modify constraint fk\_name
  foreign key (child\_column\_name)
  references parent\_table\_name (parent\_column\_name) on delete cascade;

Ça ne marche pas.

EDITAR:
La clé étrangère existe déjà, il y a des données dans la colonne de la clé étrangère.

Le message d'erreur que je reçois après avoir exécuté la déclaration :

ORA-02275: such a referential constraint already exists in the table

0 votes

Quel est le problème ? La déclaration est rejetée, la suppression n'a pas lieu

206voto

Vincent Malgrat Points 42899

Vous ne pouvez pas ajouter ON DELETE CASCADE à une contrainte déjà existante. Vous devrez drop et re- create la contrainte. Le site documentation montre que le MODIFY CONSTRAINT ne peut que modifier la clause état d'une contrainte (i-e : ENABLED/DISABLED ...).

29 votes

Il serait utile que cette réponse décrive comment cela a été fait plutôt que de pointer vers une documentation.

127voto

pradeep Points 21

Premier drop votre clé étrangère et essayez votre commande ci-dessus, mettez add constraint au lieu de modify constraint . Voici la commande :

ALTER TABLE child_table_name 
  ADD CONSTRAINT fk_name 
  FOREIGN KEY (child_column_name) 
  REFERENCES parent_table_name(parent_column_name) 
  ON DELETE CASCADE;

29 votes

Il nous donne le code entier, c'est évidemment un avantage pour les personnes qui n'ont rien à voir avec postgres.

3 votes

@WiiMaxx Fondateur d'un gars jaloux. lol Cette réponse est plus importante que la première réponse puisque cela fournit le code aussi

38voto

Comme expliqué précédemment :

ALTER TABLE TABLEName
drop CONSTRAINT FK_CONSTRAINTNAME;

ALTER TABLE TABLENAME
ADD CONSTRAINT FK_CONSTRAINTNAME
    FOREIGN KEY (FId)
    REFERENCES OTHERTABLE
        (Id)
    ON DELETE CASCADE ON UPDATE NO ACTION;

Comme vous pouvez le voir, ces commandes doivent être séparées, d'abord la chute puis l'ajout.

0 votes

Ceci n'est pas valable pour Oracle

0 votes

J'ai juste testé dans SqlServer, mais il est possible que vous ayez de la chance. go avec un point-virgule comme dans postgres et SqlServer lui-même. Mais le reste des codes de base est standard sql. Test avec les points-virgules, je viens de les modifier.

0 votes

El [ o ] sont invalides en SQL standard (et en Oracle). Oracle ne prend pas non plus en charge on update pour une clé étrangère.

25voto

bhavani Points 201

Réponse pour les utilisateurs de MYSQL :

ALTER TABLE ChildTableName 
DROP FOREIGN KEY `fk_table`;
ALTER TABLE ChildTableName 
ADD CONSTRAINT `fk_t1_t2_tt`
  FOREIGN KEY (`parentTable`)
  REFERENCES parentTable (`columnName`)
  ON DELETE CASCADE
  ON UPDATE CASCADE;

1 votes

Bienvenue sur StackOverflow. Veuillez apprendre à formater le code dans stackoverflow.com/editing-help . J'ai édité le code pour vous afin de le rendre plus lisible.

12voto

shindigo Points 447

Ce PL*SQL va écrire dans DBMS_OUTPUT un script qui va supprimer chaque contrainte qui n'a pas de cascade de suppression et la recréer avec la cascade de suppression.

NOTE : l'exécution de la sortie de ce script est à VOS PROPRES RISQUES. Le mieux est de lire le script résultant et de le modifier avant de l'exécuter.

DECLARE
      CURSOR consCols (theCons VARCHAR2, theOwner VARCHAR2) IS
        select * from user_cons_columns
            where constraint_name = theCons and owner = theOwner
            order by position;
      firstCol BOOLEAN := TRUE;
    begin
        -- For each constraint
        FOR cons IN (select * from user_constraints
            where delete_rule = 'NO ACTION'
            and constraint_name not like '%MODIFIED_BY_FK'  -- these constraints we do not want delete cascade
            and constraint_name not like '%CREATED_BY_FK'
            order by table_name)
        LOOP
            -- Drop the constraint
            DBMS_OUTPUT.PUT_LINE('ALTER TABLE ' || cons.OWNER || '.' || cons.TABLE_NAME || ' DROP CONSTRAINT ' || cons.CONSTRAINT_NAME || ';');
            -- Re-create the constraint
            DBMS_OUTPUT.PUT('ALTER TABLE ' || cons.OWNER || '.' || cons.TABLE_NAME || ' ADD CONSTRAINT ' || cons.CONSTRAINT_NAME 
                                        || ' FOREIGN KEY (');
            firstCol := TRUE;
            -- For each referencing column
            FOR consCol IN consCols(cons.CONSTRAINT_NAME, cons.OWNER)
            LOOP
                IF(firstCol) THEN
                    firstCol := FALSE;
                ELSE
                    DBMS_OUTPUT.PUT(',');
                END IF;
                DBMS_OUTPUT.PUT(consCol.COLUMN_NAME);
            END LOOP;                                    

            DBMS_OUTPUT.PUT(') REFERENCES ');

            firstCol := TRUE;
            -- For each referenced column
            FOR consCol IN consCols(cons.R_CONSTRAINT_NAME, cons.R_OWNER)
            LOOP
                IF(firstCol) THEN
                    DBMS_OUTPUT.PUT(consCol.OWNER);
                    DBMS_OUTPUT.PUT('.');
                    DBMS_OUTPUT.PUT(consCol.TABLE_NAME);        -- This seems a bit of a kluge.
                    DBMS_OUTPUT.PUT(' (');
                    firstCol := FALSE;
                ELSE
                    DBMS_OUTPUT.PUT(',');
                END IF;
                DBMS_OUTPUT.PUT(consCol.COLUMN_NAME);
            END LOOP;                                    

            DBMS_OUTPUT.PUT_LINE(')  ON DELETE CASCADE  ENABLE VALIDATE;');
        END LOOP;
    end;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X