Pular para o conteúdo principal

Questão de Banco de Dados — MySQL — FGV 2023

Banco de DadosMySQL
Código
fg072596
Banca
FGV
Órgão
TJ-SE
Ano
2023
Nível
Superior
Cargo
Analista Judiciário - Especialidade - Análise de Sistemas - Banco de Dados
O administrador de banco de dados do TJSE deverá criar um script em MySQL para realizar a carga de dados da TABELA A para a TABELA B, considerando que:• a TABELA A foi criada pelo script:CREATE TABLE a (id INT AUTO_INCREMENT PRIMARY KEY,descricao VARCHAR(255) NOT NULL,custo DECIMAL(10, 2),tipo CHAR(1), CHECK (tipo IN ('A', 'B', 'C')));• a TABELA B foi criada pelo script:CREATE TABLE b (id INT AUTO_INCREMENT PRIMARY KEY,descricao VARCHAR(255) NOT NULL,custo DECIMAL(10, 2) NOT NULL,tipo TINYINT,CHECK (tipo IN (1,2,3)));• A TABELA A foi carregada e a coluna CUSTO possui valores NULOS.O script para carregar os dados da TABELA A para a TABELA B é:
  1. AINSERT INTO bSELECT *FROM a;COMMIT;
  2. BINSERT INTO b (id, descricao, custo, tipo)SELECT id, descricao, custo, tipoFROM aWHERE custo is NOT NULL;COMMIT;
  3. CINSERT INTO b (id, descricao, custo, tipo)SELECT id, descricao, custo, tipoFROM aWHERE custo is NOT NULLAND tipo IN (1, 2, 3);COMMIT;
  4. DINSERT INTO b (id, descricao, custo, tipo)SELECT id, descricao, COALESCE(custo, 0) as custo,CASE tipoWHEN 'A' THEN 1WHEN 'B' THEN 2WHEN 'C' THEN 3END AS tipoFROM a;COMMIT;
  5. EINSERT INTO b (id, descricao, custo, tipo)SELECT id, descricao, COALESCE(custo, 0) as custo,CASE tipoWHEN 1 THEN 'A'WHEN 2 THEN 'B'WHEN 3 THEN 'C'END AS tipoFROM a;COMMIT;
Revelar gabarito e comentário

GabaritoD — INSERT INTO b (id, descricao, custo, tipo) SELECT id, descricao, COALESCE(custo, 0) as custo, CASE tipo WHEN 'A' THEN 1 WHEN 'B' THEN 2 WHEN 'C' THEN 3 END AS tipo FROM a; COMMIT;

Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.

Carga de dados entre tabelas com estruturas diferentes no MySQL

Gabarito: letra D. A única alternativa que resolve corretamente os dois problemas da migração é a D: converte valores nulos da coluna custo em zero (COALESCE) e mapeia os caracteres 'A', 'B', 'C' para os números 1,2,3 (CASE), respeitando as restrições NOT NULL e o tipo TINYINT da tabela B.

A questão exige atenção aos detalhes das definições das tabelas. A tabela A possui custo DECIMAL(10,2) (aceita NULL) e tipo CHAR(1). A tabela B possui custo DECIMAL(10,2) NOT NULL e tipo TINYINT. Portanto, qualquer script que ignore a conversão de tipos ou tente inserir NULL em custo falhará.

Alternativa A — ❌ Incorreta

INSERT INTO b SELECT * FROM a; — o SELECT * retorna as colunas de A na ordem em que foram criadas, que coincide com a ordem das colunas de B? Sim, ambas têm id, descricao, custo, tipo. Porém, o tipo CHAR(1) de A (valores 'A','B','C') não é compatível com TINYINT de B. Além disso, se houver linhas com custo nulo, a inserção falha porque a coluna custo em B é NOT NULL. Mesmo sem valores nulos, a conversão implícita de 'A' para inteiro não é garantida e pode gerar erro ou valor incorreto. Erro: não converte tipos e não trata nulos.

Alternativa B — ❌ Incorreta

INSERT INTO b ... SELECT ... WHERE custo is NOT NULL; — A condição WHERE custo is NOT NULL elimina linhas com custo nulo, o que evita o erro de NOT NULL. No entanto, o tipo da coluna tipo continua sendo CHAR em A, e o MySQL tentará inserir o caractere em uma coluna TINYINT. O MySQL pode converter 'A' para 0? Na verdade, a conversão implícita de string para número resulta em 0 para strings não numéricas (ex.: 'A' vira 0). Isso viola o CHECK tipo IN (1,2,3) da tabela B. A inserção será rejeitada ou, se o CHECK for ignorado (MySQL permite com certas configurações), insere valor 0 que não está no domínio esperado. Erro: não converte o tipo CHAR para TINYINT corretamente.

Alternativa C — ❌ Incorreta

INSERT INTO b ... SELECT ... WHERE custo is NOT NULL AND tipo IN (1,2,3); — Além do mesmo problema de conversão de tipo da alternativa B, a condição tipo IN (1,2,3) é aplicada sobre a coluna tipo da tabela A, que é CHAR. Nenhum valor CHAR é igual ao número 1,2,3 (o MySQL compara os valores convertendo ambos? Na prática, 'A' IN (1,2,3) resulta em FALSE porque 'A' convertido para número é 0, e 0 não está na lista). Portanto, a consulta não retorna nenhuma linha. Erro: filtro impossível; nunca insere dados.

Alternativa D — ✅ Correta ⟵ GABARITO

INSERT INTO b ... SELECT ... COALESCE(custo, 0) as custo, CASE tipo WHEN 'A' THEN 1 WHEN 'B' THEN 2 WHEN 'C' THEN 3 END AS tipo FROM a; — Esta alternativa resolve ambos os problemas:

  • Tratamento de NULL em custo: COALESCE(custo, 0) substitui NULL por 0, garantindo que a coluna NOT NULL receba um valor.

  • Conversão de tipo CHAR para TINYINT: a expressão CASE mapeia cada caractere para o número correspondente, produzindo valores 1,2,3 ou NULL (caso o tipo seja diferente de 'A','B','C'). Como a tabela A possui CHECK garantindo que tipo é um desses três, nunca gerará NULL. O resultado é inserido na coluna tipo TINYINT respeitando o CHECK tipo IN (1,2,3).

SE LIGUE NESSA!

A conversão é explícita e segura. Não há cláusula WHERE, portanto todas as linhas de A são inseridas, com custo nulo transformado em 0.

Alternativa E — ❌ Incorreta

INSERT INTO b ... SELECT ... COALESCE(custo, 0) as custo, CASE tipo WHEN 1 THEN 'A' WHEN 2 THEN 'B' WHEN 3 THEN 'C' END AS tipo FROM a; — O CASE está invertido. A coluna tipo em A é CHAR ('A','B','C'), então a condição WHEN 1 THEN 'A' nunca é verdadeira (tipo nunca é 1). O resultado do CASE será NULL para todas as linhas. Inserir NULL em tipo TINYINT (que não tem restrição NOT NULL, mas o CHECK permite apenas 1,2,3) falha porque NULL não está na lista. Mesmo que o CHECK permitisse NULL, o valor seria NULL, o que não é desejado. Erro: lógica do CASE invertida; não produz valores válidos para a coluna tipo.

NÃO CAIA NESSA!

A banca explora a confusão entre filtrar nulos (alternativas B e C) e a necessidade de converter os valores. Muitos candidatos escolhem a B por eliminar nulos, mas esquecem da conversão de tipo. A alternativa C adiciona um filtro impossível, tornando-se ainda pior. A alternativa D é a única que faz ambas as transformações de forma correta.

Gabarito: letra D.

Link permanente: /questoes/fg072596