Come aggiungere "ON DELETE CASCADE" nell'istruzione ALTER TABLE


130

Ho un vincolo di chiave esterna nella mia tabella, voglio aggiungere ON DELETE CASCADE ad esso.

Ho provato questo:

alter table child_table_name
  modifica il vincolo nome_fk
  chiave esterna (child_column_name)
  fa riferimento a parent_table_name (parent_column_name) su elimina cascata;

Non funziona

EDIT: la
chiave esterna esiste già, ci sono dati nella colonna chiave esterna.

Il messaggio di errore che ricevo dopo aver eseguito la dichiarazione:

ORA-02275: un tale vincolo referenziale esiste già nella tabella

Qual è il problema? La dichiarazione viene respinta, la cancellazione non si verifica.
Thorsten,

Risposte:



86

Prima la droptua chiave esterna e prova il comando sopra, metti add constraintinvece di modify constraint. Ora questo è il comando:

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

24
Ci dà l'intero codice, è un vantaggio ossessivo per le persone che non hanno nulla a che fare con Postgres
Matthis Kohli,

1
@WiiMaxx Fondatore un ragazzo di gelosia. lol Questa risposta è più importante della prima risposta poiché fornisce anche il codice.
Sono la persona più stupida del

11

Questo PL * SQL scriverà a DBMS_OUTPUT uno script che eliminerà ogni vincolo che non ha l'eliminazione in cascata e lo ricrea con l'eliminazione in cascata.

NOTA: l'esecuzione dell'output di questo script è A TUO RISCHIO. Meglio leggere lo script risultante e modificarlo prima di eseguirlo.

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;

11

Come spiegato prima:

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;

Come puoi vedere, questi devono essere comandi separati, prima di tutto, poi aggiungendo.


Questo non è valido per Oracle
a_horse_with_no_name

Appena testato in SqlServer, ma è possibile che tu abbia il caso gocon i punti e virgola come in Postgres e SqlServer stesso. Ma i codici core rimanenti sono sql standar. Prova con punti e virgola, l'ho appena cambiata
David Silva-Barrera il

Gli [o ]non sono validi in SQL standard (e Oracle). Oracle inoltre non supporta la on updateclausola per una chiave esterna.
a_horse_with_no_name

Hai ragione, [ ]sono specifici di SqlServer. Lo pulirò di più. A proposito di on updatecui non posso dire nulla.
David Silva-Barrera,

11

Risposta per UTENTI 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;

Benvenuto in StackOverflow. Per ulteriori informazioni sulla formattazione del codice, consultare stackoverflow.com/editing-help . Ho modificato il codice per renderlo più leggibile.
Adrian W,

3

Per chiunque usi MySQL:

Se vai nella tua PHPMYADMINpagina web e vai alla tabella che ha la chiave esterna che desideri aggiornare, tutto ciò che devi fare è fare clic su Relational view situato nella Structurescheda e modificare l' On deleteopzione di menu Seleziona Cascade.

Immagine mostrata di seguito:

inserisci qui la descrizione dell'immagine


OP è del 2009, la sua domanda Oracle è taggata e PHPMYADMIN è un componente software di terze parti per MySQL.
Vegatripy,

7
Assolutamente vero. Ma ho cercato su Google questa domanda, volendo sapere come farlo in MySQL e Google mi ha portato qui. Sì, la domanda è taggata con Oracle, quindi questa risposta non è corretta ... ma sarà utile per i lettori come me che si imbattono in questa risposta. Quindi non aggiungere valore a questa pagina, anche se non è Oracle specifica. Quindi, grazie James111!
Mike Gledhill

3

Ecco una soluzione pratica! Sto usando SQL Server 2008 R2.

Come si desidera modificare il vincolo FK aggiungendo ON DELETE / UPDATE CASCADE, attenersi alla seguente procedura:

NUMERO 1:

Fare clic con il tasto destro del mouse sul vincolo e fare clic su Modifica

inserisci qui la descrizione dell'immagine

NUMERO 2:

Scegli il tuo vincolo sul lato sinistro (se ce ne sono più di uno). Quindi, sul lato destro, comprimi il punto " INSERT AND UPDATE Specification " e specifica le azioni sulla riga Elimina regola o Aggiorna regola in base alle tue esigenze. Successivamente, chiudere la finestra di dialogo.

inserisci qui la descrizione dell'immagine

NUMERO 3:

Il passo finale è salvare queste modifiche (ovviamente!)

inserisci qui la descrizione dell'immagine

PS: Mi ha salvato da un sacco di lavoro in quanto voglio modificare una chiave primaria a cui fa riferimento in un'altra tabella.


Perfetto, esattamente anche quello di cui avevo bisogno!
Wildview

1

Se vuoi cambiare una chiave esterna senza lasciarla, puoi fare:

ALTER TABLE child_table_name  WITH CHECK ADD FOREIGN KEY(child_column_name)
REFERENCES parent_table_name (parent_column_name) ON DELETE CASCADE

0
ALTER TABLE `tbl_celebrity_rows` ADD CONSTRAINT `tbl_celebrity_rows_ibfk_1` FOREIGN KEY (`celebrity_id`) 
REFERENCES `tbl_celebrities`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.