18 de outubro de 2007
Para começar: a partir do MySQL mais recente, a sintaxe apresentada no título não é possível. Mas existem várias maneiras fáceis de realizar o que é esperado usando a funcionalidade existente.
Existem 3 soluções possíveis: usando INSERIR IGNORAR, SUBSTITUIR ou INSERIR ... NA DUPLICAÇÃO DE CHAVE DE ATUALIZAÇÃO.
Imagine que temos uma mesa:
CREATE TABLE `transcripts` (
`ensembl_transcript_id` varchar(20) NOT NULL,
`transcript_chrom_start` int(10) unsigned NOT NULL,
`transcript_chrom_end` int(10) unsigned NOT NULL,
PRIMARY KEY (`ensembl_transcript_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Agora imagine que temos um pipeline automático importando metadados de transcrições do Ensembl e que, devido a várias razões, o pipeline pode ser quebrado em qualquer etapa da execução. Portanto, precisamos garantir duas coisas:
execuções repetidas do pipeline não destruirão nosso banco de dados
execuções repetidas não morrem devido a erros de 'chave primária duplicada'.
Método 1: usando REPLACE
É muito simples:
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Se o registro existir, ele será substituído; se ainda não existir, será criado. No entanto, o uso desse método não é eficiente para o nosso caso: não precisamos sobrescrever registros existentes; é bom apenas ignorá-los.
Método 2: usando INSERIR IGNORE Também é muito simples:
INSERT IGNORE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Aqui, se o 'ensembl_transcript_id' já estiver presente no banco de dados, ele será ignorado silenciosamente. (Para ser mais preciso, aqui está uma citação do manual de referência do MySQL: “Se você usar a palavra-chave IGNORE, os erros que ocorrem durante a execução da instrução INSERT serão tratados como avisos. Por exemplo, sem IGNORE, uma linha que duplica um índice UNIQUE existente ou PRIMARY KEY na tabela causa um erro de chave duplicada e a instrução é interrompida. ”.) Se o registro ainda não existir, ele será criado.
Este segundo método possui várias fraquezas em potencial, incluindo o não aborto da consulta, caso ocorra outro problema (consulte o manual). Portanto, ele deve ser usado se testado anteriormente sem a palavra-chave IGNORE.
Método 3: usando INSERIR… NA ATUALIZAÇÃO DUPLICATIVA DE CHAVE:
Terceira opção é usar INSERT … ON DUPLICATE KEY UPDATE
sintaxe, e na parte UPDATE simplesmente não faça nenhuma operação sem sentido (vazia), como calcular 0 + 0 (o Geoffray sugere fazer a atribuição id = id para o mecanismo de otimização do MySQL ignorar esta operação). A vantagem desse método é que ele ignora apenas eventos-chave duplicados e ainda aborta com outros erros.
Como aviso final: este post foi inspirado no Xaprb. Também aconselho consultar seu outro post sobre como escrever consultas SQL flexíveis.