No desenvolvimento de aplicações, é comum a necessidade de inserir um registro no banco de dados se ele não existir, ou atualizá-lo caso já exista. Este artigo aborda diferentes abordagens em SQL, com foco em MySQL, para implementar essa lógica de inserção ou atualização condicional.
Abordagem 1: Usando INSERT INTO com ON DUPLICATE KEY UPDATE
No MySQL, a cláusula ON DUPLICATE KEY UPDATE permite executar uma atualização se uma chave primária ou índice único for violada durante a inserção. Por exemplo, considerando uma tabela chamada cadastro com colunas id_pessoa, nome_completo e idade:
INSERT INTO cadastro (id_pessoa, nome_completo, idade)
VALUES (101, 'ana_costa', 30)
ON DUPLICATE KEY UPDATE nome_completo = 'ana_costa', idade = 30;
Se id_pessoa = 101 não existir, o regsitro será inserido. Se já existir, o comando equivalerá a:
UPDATE cadastro
SET nome_completo = 'ana_costa', idade = 30
WHERE id_pessoa = 101;
Caso a coluna idade também seja única, a atualização ocorrerá se qualquer uma das chaves for duplicada. É recomendável evitar o uso dessa cláusula em tabelas com múltiplos índices únicos. Além disso, é possível combinar com subconsultas para atualizações em lote:
INSERT INTO cadastro (id_pessoa, nome_completo)
SELECT id_pessoa + 100, 'nome_temporario' FROM cadastro WHERE id_pessoa >= 50
ON DUPLICATE KEY UPDATE nome_completo = VALUES(nome_completo);
Abordagem 2: Utilizando Procedimentos Armazenados
Outra forma é criar um procedimento armazenado que verifica a existência antes de decidir entre inserção ou atualização:
DELIMITER //
CREATE PROCEDURE atualizar_ou_inserir(IN p_id INT, IN p_nome VARCHAR(50), IN p_idade INT)
BEGIN
IF EXISTS (SELECT 1 FROM cadastro WHERE id_pessoa = p_id) THEN
UPDATE cadastro SET nome_completo = p_nome, idade = p_idade WHERE id_pessoa = p_id;
ELSE
INSERT INTO cadastro (id_pessoa, nome_completo, idade) VALUES (p_id, p_nome, p_idade);
END IF;
END //
DELIMITER ;
Abordagem 3: Aplicando WHERE NOT EXISTS
A cláusula WHERE NOT EXISTS permite condicionar a inserção com base na ausência de registros específicos. Exemplo:
INSERT INTO cadastro (id_pessoa, nome_completo)
SELECT id_pessoa + 200, 'novo_usuario'
FROM cadastro
WHERE NOT EXISTS (
SELECT * FROM cadastro WHERE id_pessoa = 300
)
AND id_pessoa = 50;
Se a subconsulta não retornar resultados, a inserção ocorrerá com os dados fornecidos. Essa técnica é útil para inserções condicionais baseadas em critérios complexos.
Abordagem 4: Usando REPLACE INTO
O comando REPLACE INTO funciona de forma semelhante ao INSERT INTO, mas remove registros existentes que conflitam com chaves primárias ou índices únicos antes de inserir o novo regsitro. Exemplo:
REPLACE INTO cadastro (id_pessoa, nome_completo, idade)
VALUES (101, 'ana_costa_atualizada', 31);
Isso deletará o registro com id_pessoa = 101 se existir e inserirá o novo. Note que essa abordagem requer permissões de exclusão e pode afetar chaves auto-incremento. Portanto, deve ser usada com cautela, especialmente em tabelas com relacionamentos.
Ao escolher entre essas abordagens, considere fatores como desempenho, integridade dos dados e requisitos específicos do projeto.