Como adicionar 'ON DELETE CASCADE' na instrução ALTER TABLE


130

Tenho uma restrição de chave estrangeira na minha tabela, quero adicionar ON DELETE CASCADE a ela.

Eu tentei isso:

alterar tabela child_table_name
  modificar restrição fk_name
  chave estrangeira (child_column_name)
  faz referência a parent_table_name (parent_column_name) na exclusão em cascata;

Não funciona

EDIT:
chave estrangeira já existe, existem dados na coluna chave estrangeira.

A mensagem de erro recebida após a execução da instrução:

ORA-02275: essa restrição referencial já existe na tabela

Qual é o problema? A declaração é rejeitada, a exclusão não ocorre .. #
Thorsten

Respostas:



86

Primeiro dropsua chave estrangeira e tente o comando acima, coloque em add constraintvez de modify constraint. Agora este é o 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
Ele nos dá todo o código é obiously uma vantagem para as pessoas que não têm nada a ver com postgres
Matthis Kohli

1
@WiiMaxx Founder, um cara ciumento. lol Esta resposta é mais importante que a primeira resposta, pois também fornece o código ..
Eu sou a pessoa mais estúpida

11

Esse PL * SQL gravará no DBMS_OUTPUT um script que eliminará cada restrição que não possui exclusão em cascata e a recriará com exclusão em cascata.

NOTA: a execução da saída desse script é POR SUA CONTA E RISCO. É melhor ler o script resultante e editá-lo antes de executá-lo.

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

Como explicado anteriormente:

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;

Como você pode ver, esses comandos devem ser separados, largando primeiro e depois adicionando.


Isso é inválido para Oracle
a_horse_with_no_name

Apenas testado no SqlServer, mas é possível que você tenha chance gode ponto e vírgula como no postgres e no próprio SqlServer. Mas os códigos principais restantes são sql standar. Teste com ponto e vírgula, eu só mudou
David Silva-Barrera

O [ou ]é inválido no SQL padrão (e Oracle). O Oracle também não suporta on updatecláusula para uma chave estrangeira.
precisa saber é o seguinte

Você está certo, [ ]é específico do SqlServer. Vou limpar mais. Sobre on updateEu não posso dizer nada sobre.
David Silva-Barrera

11

Resposta para USUÁRIOS DO 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;

Bem-vindo ao StackOverflow. Aprenda sobre a formatação do código em stackoverflow.com/editing-help . Editei o código para torná-lo mais legível.
Adrian W

3

Para quem usa o MySQL:

Se você PHPMYADMINacessar sua página da Web e navegar para a tabela que possui a chave estrangeira que deseja atualizar, tudo o que você precisa fazer é clicar noRelational view localizado na Structureguia e alterar a On deleteopção de menu selecionar para Cascade.

Imagem mostrada abaixo:

insira a descrição da imagem aqui


O OP é de 2009, com a pergunta Oracle marcada, e o PHPMYADMIN é um componente de software de terceiros para o MySQL.
vegatripy

7
Totalmente verdade. Mas pesquisei no Google essa questão, querendo saber como fazer isso no MySQL, e o Google me trouxe aqui. Sim, a pergunta está marcada com Oracle, portanto, esta resposta não está correta ... mas será útil para leitores como eu que tropeçarem nesta resposta. Por isso, não agregar valor a esta página, mesmo que não é o Oracle específico. Então, obrigado James111!
Mike Gledhill

3

Aqui está uma solução útil! Estou usando o SQL Server 2008 R2.

Como você deseja modificar a restrição FK adicionando ON DELETE / UPDATE CASCADE, siga estas etapas:

NÚMERO 1:

Clique com o botão direito do mouse na restrição e clique em Modificar

insira a descrição da imagem aqui

NÚMERO 2:

Escolha sua restrição no lado esquerdo (se houver mais de uma). No lado direito, recolha o ponto " INSERT AND UPDATE Specification " e especifique as ações na linha Excluir regra ou Atualizar regra para atender às suas necessidades. Depois disso, feche a caixa de diálogo.

insira a descrição da imagem aqui

NÚMERO 3:

O passo final é salvar essas modificações (é claro!)

insira a descrição da imagem aqui

PS: Isso me salvou de um monte de trabalho, pois desejo modificar uma chave primária mencionada em outra tabela.


Perfeito, exatamente o que eu precisava também!
Wildview

1

Se você deseja alterar uma chave estrangeira sem soltá-la, é possível:

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;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.