Pular para o conteúdo

A primeira escola especializada em tecnologia do Alto Solimões, com corpo técnico formado na área.

Modulo 2: CRUD Basico

Deletando Dados

DELETE FROM para remover registros

DELETE -- removendo registros

O DELETE remove registros do banco de dados. A sintaxe e simples, mas o perigo tambem:

DELETE FROM tabela WHERE condicao;

DELETE basico

-- Deletar um usuario especifico
DELETE FROM usuarios WHERE id = 42;

-- Deletar pedidos cancelados
DELETE FROM pedidos WHERE status = 'cancelado';

-- Deletar logs antigos
DELETE FROM logs WHERE data_criacao < '2024-01-01';

A tecnica do SELECT antes do DELETE

Sempre teste com SELECT antes de deletar. Essa tecnica salva vidas:

-- PASSO 1: Veja o que sera deletado
SELECT id, nome, email FROM usuarios
WHERE ultimo_login < '2024-01-01'
AND status = 'inativo';
-- → Confira a lista! Sao esses mesmos?

-- PASSO 2: So entao delete
DELETE FROM usuarios
WHERE ultimo_login < '2024-01-01'
AND status = 'inativo';

DELETE com condicoes complexas

Voce pode usar todos os operadores que aprendeu no WHERE:

-- Deletar produtos sem estoque de categorias especificas
DELETE FROM produtos
WHERE estoque = 0
AND categoria IN ('eletronicos', 'informatica');

-- Deletar notificacoes lidas com mais de 30 dias
DELETE FROM notificacoes
WHERE lida = true
AND data_criacao < NOW() - INTERVAL '30 days';

-- Deletar tentativas de login falhas antigas
DELETE FROM login_tentativas
WHERE sucesso = false
AND data_tentativa < NOW() - INTERVAL '7 days';

DELETE com RETURNING (PostgreSQL)

Quer saber exatamente o que foi deletado? Use RETURNING:

DELETE FROM usuarios
WHERE status = 'inativo'
AND ultimo_login < '2023-01-01'
RETURNING id, nome, email;
-- → Retorna os dados de cada registro que foi removido

Isso e otimo para logs de auditoria ou para confirmar que deletou os registros certos.

DELETE vs TRUNCATE

-- DELETE: remove linha por linha, pode usar WHERE
DELETE FROM logs WHERE data < '2024-01-01';

-- TRUNCATE: limpa a tabela INTEIRA de uma vez
-- Nao aceita WHERE, mas e MUITO mais rapido para tabelas grandes
TRUNCATE TABLE logs;

-- TRUNCATE resetando o contador de ID (auto increment)
TRUNCATE TABLE logs RESTART IDENTITY;

Soft Delete vs Hard Delete

Na pratica, muitos sistemas nao deletam de verdade. Em vez disso, marcam o registro como "deletado":

-- Hard delete: remove do banco (irreversivel)
DELETE FROM usuarios WHERE id = 42;

-- Soft delete: marca como deletado (reversivel)
UPDATE usuarios
SET deletado_em = NOW(),
status = 'deletado'
WHERE id = 42;

-- Para "restaurar", basta limpar a marca
UPDATE usuarios
SET deletado_em = NULL,
status = 'ativo'
WHERE id = 42;

-- Nas consultas, sempre filtre os deletados
SELECT * FROM usuarios WHERE deletado_em IS NULL;

No Prisma

// Deletar um registro (exige campo unico no where)
const deletado = await prisma.usuario.delete({
where: { id: 42 }
})
// → retorna o registro que foi deletado

// Deletar varios registros
const resultado = await prisma.pedido.deleteMany({
where: { status: 'cancelado' }
})
// → resultado.count = numero de registros deletados

// Deletar todos os registros de uma tabela
const todos = await prisma.log.deleteMany()
// → cuidado! Equivale a DELETE sem WHERE

// Soft delete com Prisma
const softDelete = await prisma.usuario.update({
where: { id: 42 },
data: { deletadoEm: new Date() }
})

No Drizzle

import { eq, lt, and } from 'drizzle-orm'

// Deletar um registro
await db.delete(usuarios).where(eq(usuarios.id, 42))

// Deletar com RETURNING
const [deletado] = await db.delete(usuarios)
.where(eq(usuarios.id, 42))
.returning()

// Deletar varios registros
await db.delete(pedidos).where(eq(pedidos.status, 'cancelado'))

// Deletar com condicoes complexas
await db.delete(notificacoes).where(
and(
eq(notificacoes.lida, true),
lt(notificacoes.dataCriacao, new Date('2024-01-01'))
)
)

// Soft delete
await db.update(usuarios)
.set({ deletadoEm: new Date() })
.where(eq(usuarios.id, 42))

No Lucid (AdonisJS)

// Deletar via model
const usuario = await Usuario.findOrFail(42)
await usuario.delete()

// Deletar via query builder
const deletados = await Usuario.query()
.where('status', 'inativo')
.where('ultimo_login', '<', '2024-01-01')
.delete()
// → deletados = numero de linhas afetadas

// Soft delete com Lucid (usando coluna luxon)
const usuario = await Usuario.findOrFail(42)
usuario.deletadoEm = DateTime.now()
await usuario.save()

// Lucid tem suporte nativo a soft deletes com o mixin SoftDeletes
// No model:
import { compose } from '@adonisjs/core/helpers'
import { SoftDeletes } from 'adonis-lucid-soft-deletes'

export default class Usuario extends compose(BaseModel, SoftDeletes) {
// O mixin adiciona automaticamente:
// - delete() faz soft delete
// - forceDelete() faz hard delete
// - withTrashed() inclui deletados na busca
// - onlyTrashed() busca apenas deletados
// - restore() restaura um registro
}

Exercicios

  1. Escreva as queries (SELECT de teste + DELETE) para remover todos os logs com mais de 90 dias.
  2. Delete todos os produtos com estoque zero e que nao foram vendidos nos ultimos 6 meses.
  3. Implemente soft delete para uma tabela de comentarios: crie a query de "deletar" e a query de "buscar apenas ativos".
  4. Use RETURNING para deletar notificacoes lidas e retornar quantas foram removidas de cada usuario.
  5. Implemente o delete do exercicio 2 usando Prisma, Drizzle e Lucid.

Referencias

Testa o que você leu

5 perguntas sobre esta aula. Errar aqui não custa nada - a explicação vem junto da correção.

Pergunta 1 de 5
O que acontece ao executar `DELETE FROM usuarios` sem `WHERE`?