AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 49077
Accepted
James
James
Asked: 2013-09-02 12:39:15 +0800 CST2013-09-02 12:39:15 +0800 CST 2013-09-02 12:39:15 +0800 CST

MySQL: atualizar em vez de excluir se houver restrição de chave estrangeira?

  • 772

Eu tenho uma pergunta um pouco estranha. Eu sei sobre inserir na atualização de chave duplicada. Minha pergunta é: existe algo semelhante para exclusões que falham devido a restrições de chave estrangeira?

Por exemplo:

excluir da tabela1 onde value='something';

Porém, a tabela2 possui uma chave estrangeira que depende do valor que desejo excluir na tabela1, portanto, a exclusão falha. Eu gostaria de fazer algo assim:

excluir da tabela1 onde value='something' na chave estrangeira falha atualizar some_other_value='something else';

Sei que parece muito estranho, mas tenho um bom motivo para fazer isso (sem entrar em detalhes, tem a ver com o controle de versão de dados históricos que não podem ser destruídos caso um valor seja referenciado em outro lugar). descobrir como fazer isso com mais de uma consulta, é claro, mas gostaria de fazer isso em uma única consulta, se possível. Tenho certeza que não é possível, mas gostaria de perguntar antes de desistir :)

Obrigado!

mysql foreign-key
  • 1 1 respostas
  • 1966 Views

1 respostas

  • Voted
  1. Best Answer
    Michael - sqlbot
    2013-09-02T18:46:22+08:002013-09-02T18:46:22+08:00

    Você não pode fazer isso diretamente, pois não há como (que eu possa pensar) alternar UPDATEou DELETEda mesma consulta ... geralmente uma consulta pode fazer apenas um tipo de operação CRUD ( ON DUPLICATE KEY UPDATEsendo uma exceção a isso).

    Você poderia, no entanto, fazer com que "parecesse" uma única consulta, com um procedimento armazenado, onde você configuraria um CONTINUE HANDLERpara o erro de chave estrangeira previsto. O manipulador interceptará o erro e pode ser usado para definir uma variável que você pode testar para ver se encontrou o erro e, portanto, também precisa tentar a consulta de atualização.

    DELIMITER $$
    
    DROP PROCEDURE IF EXISTS delete_or_update $$
    CREATE PROCEDURE delete_or_update (IN input_value INT)
    BEGIN
    
      DECLARE hit_fk_error TINYINT DEFAULT 0;
      DECLARE deleted_row_count INT DEFAULT NULL;
      DECLARE updated_row_count INT DEFAULT NULL;
    
      -- 1451 is probably the error code that will be generated
      -- Cannot delete or update a parent row: a foreign key constraint fails (%s)
      -- otherwise, you may need to substitute the correct error code in the next line
    
      DECLARE CONTINUE HANDLER FOR 1451 SET hit_fk_error = TRUE;
    
      DELETE FROM parent_table WHERE tested_column = input_value; /* arg to the stored proc */
      SET deleted_row_count = ROW_COUNT();
    
      IF (hit_fk_error = TRUE) THEN
        UPDATE parent_table SET some_other_value = 'something_else'
         WHERE tested_column = input_value;
        SET updated_row_count = ROW_COUNT();
      END If;
    
      SELECT deleted_row_count, updated_row_count, hit_fk_error;
    
    END $$
    
    DELIMITER ;
    

    Isso tentará excluir; se encontrar um erro de chave estrangeira, ele tentará a atualização (e o erro de chave estrangeira será suprimido). O procedimento retornará um conjunto de registros com o número de linhas afetadas por cada consulta e se ocorreu o erro de chave estrangeira. Se o "input_value" não for um INTou a WHEREcláusula for mais complexa, você precisará modificar a estrutura de acordo.

    O problema potencial que vejo aqui é que, se a cláusula where for muito ampla e corresponder a algumas linhas que causariam um erro de chave estrangeira e outras linhas que não, a consulta não tratará as linhas individualmente. Isso poderia ser feito por um procedimento mais sofisticado que usasse um cursor para localizar as linhas na cláusula where e tentasse excluí-las ou atualizá-las individualmente por chave primária após identificá-las. Essa abordagem seria menos eficiente, mas mais precisa.

    • 3

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve