Início / Trilha 1 / Conteúdo / Tópico 5
5

Comandos SQL na Prática: SELECT, INSERT, UPDATE, DELETE

Exemplos práticos dos comandos mais usados

📖

Definição

Os 4 Comandos Fundamentais

Estes são os comandos SQL mais utilizados no dia a dia. Juntos, eles representam as operações CRUD (Create, Read, Update, Delete) que formam a base de qualquer aplicação que interage com banco de dados.

SELECT (Read)

Recupera dados do banco. É o comando mais usado - aproximadamente 80% das operações.

SELECT colunas FROM tabela WHERE condição

INSERT (Create)

Adiciona novos registros às tabelas.

INSERT INTO tabela (colunas) VALUES (valores)

UPDATE (Update)

Modifica registros existentes. Cuidado: sem WHERE afeta todos!

UPDATE tabela SET coluna = valor WHERE condição

DELETE (Delete)

Remove registros. Cuidado: sem WHERE apaga tudo!

DELETE FROM tabela WHERE condição

⚠️ Regra de Ouro para DBA

SEMPRE use WHERE em UPDATE e DELETE. Um comando sem WHERE afeta TODOS os registros da tabela.

Prática segura: Antes de executar UPDATE ou DELETE:

  1. Execute um SELECT com a mesma condição WHERE
  2. Verifique se os registros retornados são os esperados
  3. Só então execute o UPDATE/DELETE
  4. Use COMMIT apenas após confirmar o resultado
🛠️

Aplicação Prática

SELECT - Consultando Dados

-- Setup: Criar tabela de exemplo
CREATE TABLE funcionarios (
    id NUMBER PRIMARY KEY,
    nome VARCHAR2(100),
    cargo VARCHAR2(50),
    salario NUMBER(10,2),
    departamento VARCHAR2(50),
    data_admissao DATE
);

-- Inserir dados de exemplo
INSERT INTO funcionarios VALUES (1, 'João Silva', 'Analista', 5000, 'TI', DATE '2020-03-15');
INSERT INTO funcionarios VALUES (2, 'Maria Santos', 'Gerente', 8000, 'RH', DATE '2018-05-20');
INSERT INTO funcionarios VALUES (3, 'Pedro Costa', 'Desenvolvedor', 6000, 'TI', DATE '2021-01-10');
INSERT INTO funcionarios VALUES (4, 'Ana Oliveira', 'Analista', 5500, 'Financeiro', DATE '2019-08-01');
INSERT INTO funcionarios VALUES (5, 'Carlos Lima', 'Diretor', 15000, 'TI', DATE '2015-02-28');
COMMIT;

-- SELECT básico: todas as colunas
SELECT * FROM funcionarios;

-- SELECT com colunas específicas
SELECT nome, cargo, salario FROM funcionarios;

-- SELECT com WHERE (filtro)
SELECT nome, salario
FROM funcionarios
WHERE departamento = 'TI';

-- SELECT com múltiplas condições
SELECT nome, cargo, salario
FROM funcionarios
WHERE departamento = 'TI'
  AND salario > 5000;

-- SELECT com OR
SELECT nome, departamento
FROM funcionarios
WHERE departamento = 'TI'
   OR departamento = 'RH';

-- Equivalente com IN
SELECT nome, departamento
FROM funcionarios
WHERE departamento IN ('TI', 'RH');

-- SELECT com BETWEEN (intervalo)
SELECT nome, salario
FROM funcionarios
WHERE salario BETWEEN 5000 AND 8000;

-- SELECT com LIKE (padrão)
SELECT nome FROM funcionarios WHERE nome LIKE 'Jo%';      -- Começa com "Jo"
SELECT nome FROM funcionarios WHERE nome LIKE '%Silva';   -- Termina com "Silva"
SELECT nome FROM funcionarios WHERE nome LIKE '%ar%';    -- Contém "ar"

-- SELECT com NULL
SELECT nome FROM funcionarios WHERE cargo IS NULL;
SELECT nome FROM funcionarios WHERE cargo IS NOT NULL;

-- SELECT com ORDER BY
SELECT nome, salario
FROM funcionarios
ORDER BY salario DESC;  -- Decrescente

SELECT nome, departamento, salario
FROM funcionarios
ORDER BY departamento ASC, salario DESC;  -- Multi-coluna

-- SELECT com alias
SELECT
    nome AS "Nome Completo",
    salario AS "Salário Mensal",
    salario * 12 AS "Salário Anual"
FROM funcionarios;

INSERT - Inserindo Dados

-- INSERT básico: especificando todas as colunas
INSERT INTO funcionarios (id, nome, cargo, salario, departamento, data_admissao)
VALUES (6, 'Fernanda Rocha', 'Analista', 5200, 'Marketing', DATE '2022-06-01');

-- INSERT sem especificar colunas (ordem deve ser a mesma da tabela)
INSERT INTO funcionarios
VALUES (7, 'Ricardo Souza', 'Estagiário', 1500, 'TI', SYSDATE);

-- INSERT parcial (colunas com NULL ou DEFAULT)
INSERT INTO funcionarios (id, nome, cargo, departamento)
VALUES (8, 'Luciana Mendes', 'Consultora', 'Externo');
-- salario ficará NULL, data_admissao também (se não tiver DEFAULT)

-- INSERT com subconsulta
INSERT INTO funcionarios_backup
SELECT * FROM funcionarios WHERE departamento = 'TI';

-- INSERT múltiplos registros (Oracle)
INSERT ALL
    INTO funcionarios VALUES (9, 'Bruno Alves', 'Analista', 5300, 'TI', SYSDATE)
    INTO funcionarios VALUES (10, 'Carla Dias', 'Designer', 4800, 'Marketing', SYSDATE)
SELECT * FROM dual;

-- INSERT com RETURNING (captura valor gerado)
DECLARE
    v_id NUMBER;
BEGIN
    INSERT INTO funcionarios (id, nome, cargo, salario, departamento, data_admissao)
    VALUES (seq_func.NEXTVAL, 'Novo Funcionário', 'Analista', 5000, 'TI', SYSDATE)
    RETURNING id INTO v_id;

    DBMS_OUTPUT.PUT_LINE('ID inserido: ' || v_id);
END;
/

COMMIT;

UPDATE - Atualizando Dados

-- PASSO 1: SEMPRE verificar antes com SELECT
SELECT id, nome, salario
FROM funcionarios
WHERE departamento = 'TI';

-- PASSO 2: Se os registros estão corretos, executar UPDATE
-- UPDATE simples: uma coluna
UPDATE funcionarios
SET salario = 5500
WHERE id = 1;

-- UPDATE múltiplas colunas
UPDATE funcionarios
SET salario = 6500,
    cargo = 'Analista Sênior'
WHERE id = 1;

-- UPDATE com cálculo
UPDATE funcionarios
SET salario = salario * 1.10  -- Aumento de 10%
WHERE departamento = 'TI';

-- UPDATE com subconsulta
UPDATE funcionarios f
SET salario = (
    SELECT AVG(salario)
    FROM funcionarios
    WHERE departamento = f.departamento
)
WHERE cargo = 'Estagiário';

-- UPDATE condicional com CASE
UPDATE funcionarios
SET salario = CASE
    WHEN cargo = 'Diretor' THEN salario * 1.05
    WHEN cargo = 'Gerente' THEN salario * 1.08
    WHEN cargo = 'Analista' THEN salario * 1.10
    ELSE salario * 1.07
END;

-- Verificar resultado
SELECT id, nome, cargo, salario FROM funcionarios;

-- Se OK, confirmar
COMMIT;

-- Se NÃO OK, desfazer
-- ROLLBACK;

💡 Dica: UPDATE Seguro

-- Antes do UPDATE perigoso, crie um backup
CREATE TABLE funcionarios_bkp AS SELECT * FROM funcionarios;

-- Execute o UPDATE
UPDATE funcionarios SET salario = salario * 1.5 WHERE departamento = 'TI';

-- Se algo deu errado, restaure
-- INSERT INTO funcionarios SELECT * FROM funcionarios_bkp WHERE ...
-- ou
-- ROLLBACK; (se ainda não fez COMMIT)

DELETE - Removendo Dados

-- PASSO 1: SEMPRE verificar antes com SELECT
SELECT * FROM funcionarios
WHERE data_admissao < DATE '2016-01-01';

-- PASSO 2: Se os registros estão corretos, executar DELETE
-- DELETE simples
DELETE FROM funcionarios
WHERE id = 8;

-- DELETE com múltiplas condições
DELETE FROM funcionarios
WHERE departamento = 'Externo'
  AND cargo = 'Consultora';

-- DELETE com subconsulta
DELETE FROM funcionarios
WHERE departamento IN (
    SELECT nome FROM departamentos WHERE ativo = 'N'
);

-- DELETE com EXISTS
DELETE FROM funcionarios f
WHERE NOT EXISTS (
    SELECT 1 FROM departamentos d
    WHERE d.nome = f.departamento
);

-- Verificar resultado
SELECT COUNT(*) FROM funcionarios;

-- Confirmar ou desfazer
COMMIT;
-- ROLLBACK;

⚠️ PERIGO: DELETE sem WHERE

-- NUNCA faça isso sem ter certeza absoluta:
DELETE FROM funcionarios;  -- Apaga TODOS os registros!

-- Diferença entre DELETE e TRUNCATE:
-- DELETE: Pode ser revertido com ROLLBACK, gera log, dispara triggers
-- TRUNCATE: NÃO pode ser revertido, mais rápido, não dispara triggers

TRUNCATE TABLE funcionarios;  -- DDL: COMMIT automático, sem volta!

Cenário Completo: Fluxo de Trabalho Seguro

-- CENÁRIO: Corrigir salários do departamento de TI
-- Os salários devem ser aumentados em 15% para analistas

-- 1. Criar ponto de salvamento
SAVEPOINT antes_correcao;

-- 2. Verificar dados atuais
SELECT id, nome, cargo, salario, departamento
FROM funcionarios
WHERE departamento = 'TI' AND cargo = 'Analista';
-- Resultado: 2 registros (ids 1 e 3)

-- 3. Verificar valor esperado
SELECT id, nome, salario, salario * 1.15 AS novo_salario
FROM funcionarios
WHERE departamento = 'TI' AND cargo = 'Analista';

-- 4. Executar UPDATE
UPDATE funcionarios
SET salario = salario * 1.15
WHERE departamento = 'TI' AND cargo = 'Analista';
-- "2 rows updated"

-- 5. Verificar resultado
SELECT id, nome, cargo, salario
FROM funcionarios
WHERE departamento = 'TI';

-- 6a. Se CORRETO: Confirmar
COMMIT;
DBMS_OUTPUT.PUT_LINE('Correção aplicada com sucesso!');

-- 6b. Se INCORRETO: Reverter
-- ROLLBACK TO SAVEPOINT antes_correcao;
-- ou simplesmente
-- ROLLBACK;

Resultado Esperado

O que você deve dominar após este tópico:

SELECT completo

WHERE, ORDER BY, LIKE, BETWEEN, IN, IS NULL

INSERT variado

Simples, múltiplo, com subconsulta

UPDATE seguro

Sempre verificar antes com SELECT

DELETE consciente

Verificar registros afetados antes

Transações

COMMIT, ROLLBACK, SAVEPOINT

Práticas seguras

Backup antes de operações arriscadas

📝

Exercícios Práticos

Exercício 1: SELECT com Filtros

Usando a tabela FUNCIONARIOS, escreva queries para:

  1. Listar nome e salário de quem ganha mais de 6000
  2. Listar funcionários do TI ou Marketing ordenados por nome
  3. Listar funcionários cujo nome contém "Silva" ou "Santos"
  4. Listar funcionários admitidos em 2020 ou depois
Ver Solução
-- 1. Salário > 6000
SELECT nome, salario
FROM funcionarios
WHERE salario > 6000;

-- 2. TI ou Marketing ordenados
SELECT nome, departamento
FROM funcionarios
WHERE departamento IN ('TI', 'Marketing')
ORDER BY nome;

-- 3. Nome contém Silva ou Santos
SELECT nome
FROM funcionarios
WHERE nome LIKE '%Silva%' OR nome LIKE '%Santos%';

-- 4. Admitidos em 2020+
SELECT nome, data_admissao
FROM funcionarios
WHERE data_admissao >= DATE '2020-01-01'
ORDER BY data_admissao;

Exercício 2: CRUD Completo

Execute as seguintes operações na tabela FUNCIONARIOS:

  1. Insira um novo funcionário: "Mariana Costa", Analista de Dados, R$ 7000, TI
  2. Atualize o cargo de "João Silva" para "Analista Pleno"
  3. Aumente em 5% o salário de todos os Analistas
  4. Delete o funcionário com menor salário (mas verifique primeiro!)
Ver Solução
-- 1. INSERT
INSERT INTO funcionarios (id, nome, cargo, salario, departamento, data_admissao)
VALUES (11, 'Mariana Costa', 'Analista de Dados', 7000, 'TI', SYSDATE);

-- 2. UPDATE específico (primeiro verificar)
SELECT * FROM funcionarios WHERE nome = 'João Silva';
UPDATE funcionarios SET cargo = 'Analista Pleno' WHERE nome = 'João Silva';

-- 3. UPDATE com cálculo (verificar antes)
SELECT nome, cargo, salario, salario * 1.05 AS novo_salario
FROM funcionarios WHERE cargo LIKE '%Analista%';

UPDATE funcionarios
SET salario = salario * 1.05
WHERE cargo LIKE '%Analista%';

-- 4. DELETE (verificar ANTES!)
SELECT * FROM funcionarios
WHERE salario = (SELECT MIN(salario) FROM funcionarios);

-- Se correto, deletar
DELETE FROM funcionarios
WHERE salario = (SELECT MIN(salario) FROM funcionarios);

-- Confirmar todas as mudanças
COMMIT;

Exercício 3: Transação com SAVEPOINT

Simule um processo de ajuste salarial com pontos de salvamento:

  1. Crie um SAVEPOINT inicial
  2. Aumente 10% para TI
  3. Crie outro SAVEPOINT
  4. Aumente 15% para Gerentes
  5. Verifique os resultados
  6. Volte ao segundo SAVEPOINT (desfazer aumento dos gerentes)
  7. Confirme apenas o aumento do TI
Ver Solução
-- 1. SAVEPOINT inicial
SAVEPOINT inicio;

-- 2. Aumento TI
UPDATE funcionarios SET salario = salario * 1.10
WHERE departamento = 'TI';

-- 3. SAVEPOINT após TI
SAVEPOINT apos_ti;

-- 4. Aumento Gerentes
UPDATE funcionarios SET salario = salario * 1.15
WHERE cargo = 'Gerente';

-- 5. Verificar
SELECT nome, cargo, departamento, salario FROM funcionarios
ORDER BY departamento, cargo;

-- 6. Voltar ao SAVEPOINT após TI (desfaz aumento gerentes)
ROLLBACK TO SAVEPOINT apos_ti;

-- Verificar que gerentes voltaram ao valor anterior
SELECT nome, cargo, salario FROM funcionarios WHERE cargo = 'Gerente';

-- 7. Confirmar apenas TI
COMMIT;
Anterior: Linguagem SQL Próximo: JOINs e Subqueries