SQL DELETE: Remover Linhas de uma Tabela
Lição 8.3 · Tempo de leitura: ~6 min · Tarefas para praticar ↓
A instrução SQL DELETE remove linhas de uma tabela. Nesta lição, você vai aprender a sintaxe DELETE ... WHERE, como remover linhas por uma condição noutra tabela, por que as chaves estrangeiras às vezes bloqueiam uma remoção, como verificar um DELETE antes de executá-lo e em que ele difere do TRUNCATE.
O DELETE é a última das três instruções de alteração de dados. É a mais simples de escrever e a mais perigosa: uma única condição esquecida remove todas as linhas de uma tabela. As regras desta lição servem para remover exatamente as linhas que você pretende.
Os bancos de exemplo do SQLtest são somente leitura, por isso estas instruções devolvem ali um erro de permissão. Os exemplos usam o esquema Sakila.
Sintaxe do DELETE
DELETE FROM table_name
WHERE condition;
DELETE FROMindica a tabela.WHEREseleciona as linhas a remover. SemWHERE, todas as linhas são removidas.- Só as linhas são removidas: a tabela, as suas colunas e índices permanecem.
Remover Linhas por uma Condição
DELETE FROM payment
WHERE payment_date < '2005-05-25';
Resultado: todos os pagamentos feitos antes de 25 de maio de 2005 são removidos.
Remover pela chave primária remove exatamente uma linha:
DELETE FROM payment
WHERE payment_id = 16049;
Remover por uma Condição Noutra Tabela
Uma subconsulta no WHERE seleciona linhas com base em dados de outras tabelas. Remova os pagamentos de clientes inativos:
DELETE FROM payment
WHERE customer_id IN (
SELECT customer_id
FROM customer
WHERE active = 0
);
Resultado: todos os pagamentos dos 15 clientes inativos são removidos.
Tal como no UPDATE, MySQL e MariaDB não permitem que a subconsulta leia a tabela de onde se remove. O MySQL também suporta uma forma de várias tabelas: DELETE p FROM payment AS p INNER JOIN customer AS c ON c.customer_id = p.customer_id WHERE c.active = 0;.
Chaves Estrangeiras Podem Bloquear um DELETE
Outras tabelas referenciam os clientes: rental e payment guardam customer_id. No Sakila, essas chaves estrangeiras são definidas com ON DELETE RESTRICT, por isso o banco de dados recusa remover um cliente que ainda tem aluguéis ou pagamentos:
DELETE FROM customer
WHERE customer_id = 1;
Resultado: um erro "Cannot delete or update a parent row: a foreign key constraint fails". O cliente permanece.
Isso protege os dados: sem isso, haveria aluguéis apontando para um cliente que já não existe. Para remover um cliente assim, primeiro remova ou reatribua as linhas dependentes, ou a chave estrangeira tem de estar definida com ON DELETE CASCADE, que as remove automaticamente. Você vai aprender as opções de chave estrangeira junto com CREATE TABLE na Lição 9.1.
Verificar Antes de Remover
- Execute um
SELECTcom o mesmoWHEREe veja as linhas. - Execute o
DELETEe compare o número de linhas afetadas.
-- 1. Que linhas serão removidas?
SELECT payment_id, customer_id, amount, payment_date
FROM payment
WHERE payment_date < '2005-05-25';
-- 2. Remover exatamente essas linhas
DELETE FROM payment
WHERE payment_date < '2005-05-25';
Em produção, execute as remoções importantes numa transação e confirme que existe um backup. Muitos sistemas não removem dados de negócio de todo: marcam as linhas como removidas (active = 0, deleted_at), o que se chama remoção lógica (soft delete).
DELETE Sem WHERE e TRUNCATE
DELETE FROM table_name; remove todas as linhas, mas mantém a tabela. TRUNCATE TABLE table_name; faz o mesmo muito mais depressa, mas funciona de outra forma:
DELETE | TRUNCATE | |
|---|---|---|
| Pode remover só parte das linhas | Sim, com WHERE | Não, sempre todas |
| Velocidade em tabelas grandes | Mais lento, linha a linha | Rápido |
| Reinicia o autoincremento | Não | Sim |
| Bloqueado por chaves estrangeiras | Só para linhas referenciadas | Se qualquer tabela referencia esta |
Você vai aprender TRUNCATE e DROP TABLE na Lição 9.3.
Principais conclusões:
DELETE FROM table WHERE conditionremove as linhas correspondentes; a tabela permanece.- Sem
WHERE, todas as linhas são removidas. - Uma subconsulta no
WHEREremove linhas por condições noutras tabelas. - Chaves estrangeiras com
RESTRICTbloqueiam a remoção de linhas ainda referenciadas. - Verifique primeiro com
SELECT; use transações e backups em remoções importantes. - Para esvaziar rapidamente uma tabela inteira, use
TRUNCATE.
Perguntas Frequentes
O que acontece se eu executar DELETE sem WHERE?
Todas as linhas da tabela são removidas; a tabela vazia permanece. A menos que a instrução tenha sido executada numa transação que você possa reverter, os dados só podem ser recuperados de um backup.
Por que não consigo remover uma linha em SQL?
Normalmente por causa de uma chave estrangeira: outra tabela ainda referencia a linha. Remova ou altere primeiro as linhas dependentes, ou defina a chave estrangeira com ON DELETE CASCADE.
Qual é a diferença entre DELETE e TRUNCATE?
O DELETE remove as linhas uma a uma e pode usar WHERE; o TRUNCATE remove todas as linhas de uma vez, é muito mais rápido e reinicia o contador de autoincremento.