UPDATE: modificando dados existentes

1. Sintaxe Básica do Comando UPDATE

O comando UPDATE é a instrução SQL responsável por modificar registros já existentes em uma tabela. Sua estrutura fundamental é direta, mas poderosa:

UPDATE nome_da_tabela
SET coluna = novo_valor
WHERE condição;

Para atualizar uma única coluna em um registro específico:

UPDATE funcionarios
SET cargo = 'Analista Sênior'
WHERE id_funcionario = 42;

Quando precisamos modificar múltiplas colunas simultaneamente, separamos as atribuições por vírgulas:

UPDATE funcionarios
SET cargo = 'Gerente',
    salario = 9500.00,
    data_promocao = '2024-03-15'
WHERE id_funcionario = 15;

2. A Cláusula WHERE: Precisão é Tudo

A cláusula WHERE é o componente mais crítico do UPDATE. Sem ela, todos os registros da tabela serão alterados — um erro que pode ter consequências devastadoras.

Usando operadores de comparação:

-- Atualizar funcionários com salário abaixo de 3000
UPDATE funcionarios
SET salario = 3200
WHERE salario < 3000;

-- Atualizar exceto um cargo específico
UPDATE funcionarios
SET ativo = false
WHERE cargo != 'Presidente';

Combinando condições com operadores lógicos:

UPDATE pedidos
SET status = 'prioritario'
WHERE valor_total > 5000
  AND data_pedido >= '2024-01-01'
  AND (status = 'pendente' OR status = 'processando');

3. Atualizando Múltiplas Linhas de Uma Vez

Uma das grandes vantagens do SQL é modificar vários registros com um único comando:

-- Atualizar todos os produtos de uma categoria
UPDATE produtos
SET desconto = 0.15
WHERE categoria = 'Eletrônicos';

-- Usando BETWEEN para intervalo
UPDATE produtos
SET preco = preco * 0.9
WHERE id_produto BETWEEN 100 AND 200;

-- Usando IN para lista de valores
UPDATE funcionarios
SET departamento = 'Inovação'
WHERE id_departamento IN (3, 5, 7);

Para tabelas grandes, considere atualizações em lotes com transações para evitar bloqueios prolongados:

UPDATE vendas
SET processado = true
WHERE data_venda < '2024-01-01'
  AND processado = false
LIMIT 1000;  -- Sintaxe MySQL

4. Expressões e Funções no SET

O SET aceita expressões complexas, permitindo transformações durante a atualização:

Operações aritméticas:

-- Aumento salarial de 10%
UPDATE funcionarios
SET salario = salario * 1.10
WHERE desempenho = 'excelente';

-- Aplicar desconto progressivo
UPDATE produtos
SET preco_final = preco_base * (1 - desconto/100);

Funções de string e data:

-- Padronizar nomes em maiúsculas
UPDATE clientes
SET nome = UPPER(nome);

-- Atualizar data de expiração
UPDATE assinaturas
SET data_expiracao = DATE_ADD(data_expiracao, INTERVAL 30 DAY)
WHERE status = 'ativo';

-- Concatenar informações
UPDATE usuarios
SET nome_completo = CONCAT(primeiro_nome, ' ', ultimo_nome);

5. UPDATE com Subconsultas

Subconsultas permitem basear atualizações em dados de outras tabelas:

Subconsulta escalar no SET:

UPDATE produtos
SET preco = (SELECT AVG(preco) FROM produtos WHERE categoria = 'Periféricos')
WHERE categoria = 'Teclados';

Subconsulta correlacionada para lógica mais refinada:

UPDATE funcionarios f
SET salario = salario * 1.15
WHERE (SELECT AVG(salario) FROM funcionarios WHERE departamento = f.departamento) < 5000;

Atualizando com JOIN implícito:

UPDATE pedidos p
SET p.status = 'cancelado'
WHERE p.id_cliente IN (
    SELECT id_cliente FROM clientes WHERE status_conta = 'bloqueada'
);

6. Integridade Referencial e Constraints

Constraints podem impedir ou complicar operações de UPDATE:

Violação de chave estrangeira:

-- Pode falhar se houver pedidos referenciando este cliente
UPDATE clientes
SET id_cliente = 999
WHERE id_cliente = 10;
-- Erro: violação de chave estrangeira

Estratégia com ON UPDATE CASCADE:

CREATE TABLE pedidos (
    id_pedido INT PRIMARY KEY,
    id_cliente INT,
    FOREIGN KEY (id_cliente) REFERENCES clientes(id_cliente)
    ON UPDATE CASCADE
);

-- Agora este UPDATE propagará a mudança automaticamente
UPDATE clientes
SET id_cliente = 999
WHERE id_cliente = 10;

Constraints UNIQUE e CHECK:

-- UNIQUE: não pode criar duplicatas
UPDATE usuarios
SET email = 'novo@email.com'
WHERE id = 5;
-- Falha se outro usuário já tiver este email

-- CHECK: validação de regras de negócio
UPDATE produtos
SET preco = -10
WHERE id = 1;
-- Falha se houver CHECK (preco > 0)

7. Transações e Rollback: Segurança em Primeiro Lugar

Transações são essenciais para operações críticas:

BEGIN TRANSACTION;

UPDATE contas
SET saldo = saldo - 500
WHERE id_conta = 1001;

UPDATE contas
SET saldo = saldo + 500
WHERE id_conta = 2002;

-- Verificar antes de confirmar
SELECT * FROM contas WHERE id_conta IN (1001, 2002);

COMMIT;
-- Ou ROLLBACK se algo estiver errado

Prática recomendada: testar com SELECT antes do UPDATE:

-- Primeiro, verifique quais registros serão afetados
SELECT id, nome, salario
FROM funcionarios
WHERE departamento = 'TI';

-- Depois, execute o UPDATE dentro de uma transação
BEGIN;
UPDATE funcionarios
SET salario = salario * 1.2
WHERE departamento = 'TI';

-- Verifique o resultado
SELECT id, nome, salario
FROM funcionarios
WHERE departamento = 'TI';

COMMIT; -- ou ROLLBACK;

8. Boas Práticas e Armadilhas Comuns

Sempre use WHERE — a menos que a intenção seja literalmente atualizar toda a tabela:

-- Correto: intencional
UPDATE logs_auditoria
SET processado = true;

-- Perigoso: esqueceu o WHERE
UPDATE clientes
SET email = 'admin@empresa.com';
-- Todos os clientes perderiam seus emails!

Backup ou snapshot antes de operações críticas:

-- Criar tabela de backup
CREATE TABLE funcionarios_backup AS SELECT * FROM funcionarios;

-- Ou em muitos SGBDs, usar snapshots/point-in-time recovery

Evitando deadlocks em ambientes concorrentes:

  • Atualize registros em uma ordem consistente (ex: por ID crescente)
  • Mantenha transações curtas
  • Use isolamento adequado (READ COMMITTED geralmente é suficiente)

Outras armadilhas comuns:

-- Cuidado com NULL: NULL != NULL
UPDATE produtos
SET desconto = 0.1
WHERE desconto = NULL;  -- Nunca é verdadeiro!

-- Correto:
UPDATE produtos
SET desconto = 0.1
WHERE desconto IS NULL;

Referências