Pular para o conteúdo principal

Questão de Banco de Dados — Oracle — FGV 2024

Banco de DadosOracle
Código
fg165212
Banca
FGV
Órgão
TJ AP
Ano
2024
Cargo
AJ ( )
Observe o seguinte script de criação da tabela “Empresa” e outros objetos em Oracle:   CREATE TABLE empresa (     empresa_ID NUMBER(12) PRIMARY KEY,     razao_social VARCHAR2(50) NOT NULL );   CREATE SEQUENCE sq_empresa_pk   START WITH 2   INCREMENT BY 2   NOMAXVALUE   NOCACHE   NOCYCLE;   CREATE OR REPLACE TRIGGER trg_bi_empresa     BEFORE INSERT ON empresa     FOR EACH ROW WHEN (NEW.empresa_ID IS NULL) BEGIN     SELECT sq_empresa_pk.NEXTVAL INTO :NEW.empresa_ID FROM dual; END;   Após a execução do script anteriormente apresentado, analise a execução dos seguintes comandos:   INSERT INTO empresa (empresa_ID, razao_social) VALUES (NULL, 'AAA'); INSERT INTO empresa (razao_social) VALUES ('BBB'); INSERT INTO empresa (empresa_ID, razao_social) VALUES (1, 'CCC'); INSERT INTO empresa (empresa_ID, razao_social) VALUES (5, 'DDD'); INSERT INTO empresa (empresa_ID, razao_social) VALUES (6, 'EEE'); INSERT INTO empresa (razao_social) VALUES ('FFF'); COMMIT;   Após a execução dos comandos apresentados, é correto afirmar que:
  1. Aforam inseridas 6 (seis) linhas e o número final para sq_empresa_pk.CURRVAL é igual a 6 (seis);
  2. Bnenhuma linha pode ser inserida e o número final para sq_empresa_pk.CURRVAL é igual a 2 (dois);
  3. Cforam inseridas 5 (cinco) linhas e o número final para sq_empresa_pk.CURRVAL é igual a 6 (seis);
  4. Dforam inseridas 5 (cinco) linhas e o número final para sq_empresa_pk.CURRVAL é igual a 4 (quatro);
  5. Eforam inseridas 4 (quatro) linhas e o número final para sq_empresa_pk.CURRVAL é igual a 4 (quatro).
Revelar gabarito e comentário

GabaritoC — foram inseridas 5 (cinco) linhas e o número final para sq_empresa_pk.CURRVAL é igual a 6 (seis);

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”.

Trigger BEFORE INSERT e Sequence no Oracle: comportamento do NEXTVAL

Gabarito: letra C. Foram inseridas 5 (cinco) linhas e o valor final de sq_empresa_pk.CURRVAL é 6 (seis). A trigger BEFORE INSERT dispara apenas quando empresa_ID é NULL, gerando o próximo valor da sequence (2, 4, 6...); quando o INSERT fornece um valor explícito, a trigger não é acionada e a sequence não é consumida — por isso o INSERT com empresa_ID = 1 e o com empresa_ID = 5 não avançam a sequence, mas o INSERT com empresa_ID = 6 também não a consome, pois o valor já vem preenchido. O INSERT com NULL explícito e os dois INSERT sem a coluna empresa_ID disparam a trigger, consumindo os valores 2, 4 e 6 da sequence.

A questão combina dois mecanismos do Oracle: sequences (geradores de números sequenciais) e triggers (blocos PL/SQL executados automaticamente em eventos de DML). A trigger trg_bi_empresa é do tipo BEFORE INSERT FOR EACH ROW com a condição WHEN (NEW.empresa_ID IS NULL). Isso significa que, para cada linha inserida, o Oracle verifica se o valor da coluna empresa_ID na nova linha é nulo; se for, executa o bloco que busca sq_empresa_pk.NEXTVAL e atribui a :NEW.empresa_ID. Se o valor já foi fornecido (não nulo), a trigger não executa e a sequence não é tocada.

A sequence sq_empresa_pk foi criada com START WITH 2 INCREMENT BY 2, ou seja, os valores gerados são 2, 4, 6, 8, ... (sempre pares, começando em 2). O NOCACHE e NOCYCLE não alteram essa lógica: NOCACHE apenas impede o pré-carregamento de valores em memória (cada NEXTVAL acessa o dicionário), e NOCYCLE impede que a sequence recomece após atingir o máximo (aqui, NOMAXVALUE). O ponto crucial é que a sequence só é incrementada quando NEXTVAL é chamado — e isso só ocorre dentro da trigger, ou seja, apenas quando o INSERT não fornece um valor para empresa_ID.

Vamos analisar cada INSERT:

  1. INSERT INTO empresa (empresa_ID, razao_social) VALUES (NULL, 'AAA'); — Aqui, empresa_ID é NULL explícito. A trigger dispara, chama NEXTVAL (que retorna 2) e insere a linha com empresa_ID = 2. A sequence agora está em 2.

  2. INSERT INTO empresa (razao_social) VALUES ('BBB'); — A coluna empresa_ID não é mencionada, então recebe NULL (padrão). A trigger dispara, chama NEXTVAL (que retorna 4) e insere a linha com empresa_ID = 4. A sequence agora está em 4.

  3. INSERT INTO empresa (empresa_ID, razao_social) VALUES (1, 'CCC');empresa_ID é 1 (não nulo). A trigger não dispara. A linha é inserida com empresa_ID = 1. A sequence não é consumida.

  4. INSERT INTO empresa (empresa_ID, razao_social) VALUES (5, 'DDD');empresa_ID é 5 (não nulo). A trigger não dispara. A linha é inserida com empresa_ID = 5. A sequence não é consumida.

  5. INSERT INTO empresa (empresa_ID, razao_social) VALUES (6, 'EEE');empresa_ID é 6 (não nulo). A trigger não dispara. A linha é inserida com empresa_ID = 6. A sequence não é consumida.

  6. INSERT INTO empresa (razao_social) VALUES ('FFF'); — A coluna empresa_ID não é mencionada, então recebe NULL. A trigger dispara, chama NEXTVAL (que retorna 6) e insere a linha com empresa_ID = 6. A sequence agora está em 6.

Após o COMMIT, todas as 6 linhas são persistidas. No entanto, a alternativa C afirma que foram inseridas 5 linhas. Isso é um erro? Não — a pegadinha está na restrição de chave primária. A tabela empresa tem empresa_ID NUMBER(12) PRIMARY KEY, o que significa que não pode haver valores duplicados. No passo 5, inserimos empresa_ID = 6; no passo 6, a trigger gera empresa_ID = 6 novamente. Como já existe uma linha com empresa_ID = 6, o INSERT do passo 6 falha por violação de chave primária (erro ORA-00001). Portanto, apenas 5 linhas são efetivamente inseridas: as dos passos 1, 2, 3, 4 e 5. A sequence, porém, já foi incrementada para 6 no passo 6 (o NEXTVAL foi chamado antes da falha), então CURRVAL retorna 6.

NÃO CAIA NESSA!

A banca explora a violação de chave primária que ocorre no último INSERT. O candidato conta 6 INSERTs e assume que 6 linhas foram inseridas, esquecendo que a trigger gera empresa_ID = 6 que já existe (inserido explicitamente no passo 5). A sequence é incrementada antes da verificação de unicidade, então CURRVAL reflete o valor gerado, mesmo que a linha não seja inserida. Fique atento: NEXTVAL é consumido antes da checagem de constraints.

Critério

INSERTs com empresa_ID nulo/omitido (disparam trigger)

INSERTs com empresa_ID explícito (não disparam trigger)

Quantidade de comandos

3 (passos 1, 2 e 6)

3 (passos 3, 4 e 5)

Valores gerados pela sequence

2, 4 e 6 (consumidos via NEXTVAL)

Nenhum (sequence não é tocada)

Linhas efetivamente inseridas

2 (passos 1 e 2; passo 6 falha por PK duplicada)

3 (passos 3, 4 e 5)

Resultado final

CURRVAL = 6

Total de 5 linhas inseridas

Alternativa A — ❌ Incorreta

Afirma que foram inseridas 6 linhas e CURRVAL = 6. O CURRVAL está correto, mas o número de linhas está errado: o último INSERT falha por duplicidade de chave primária (empresa_ID = 6 já existe), então apenas 5 linhas são inseridas. A banca conta os 6 comandos INSERT sem considerar a falha.

Alternativa B — ❌ Incorreta

Afirma que nenhuma linha foi inserida e CURRVAL = 2. Totalmente equivocado: os cinco primeiros INSERTs são válidos e inserem linhas. A sequence é consumida nos passos 1, 2 e 6, chegando a 6, não 2. O valor 2 seria o primeiro NEXTVAL, mas a sequence avança a cada chamada.

Alternativa C — ✅ Correta ⟵ GABARITO

Correta: 5 linhas são inseridas (passos 1 a 5) e CURRVAL = 6. O passo 6 falha por violação de chave primária, mas a sequence já foi incrementada para 6 antes da falha. A alternativa espelha exatamente o comportamento: a trigger só consome a sequence quando empresa_ID é nulo, e a duplicidade impede a inserção da última linha.

Alternativa D — ❌ Incorreta

Afirma 5 linhas inseridas (correto) mas CURRVAL = 4 (errado). A sequence é chamada três vezes (passos 1, 2 e 6), gerando 2, 4 e 6. O valor 4 seria o segundo NEXTVAL, mas o terceiro chamado (passo 6) avança para 6. A banca pode ter esquecido que o passo 6 também consome a sequence, mesmo falhando.

Alternativa E — ❌ Incorreta

Afirma 4 linhas inseridas e CURRVAL = 4. O número de linhas está errado (são 5) e o CURRVAL também (é 6). A combinação não corresponde a nenhum cenário real: a sequence é consumida três vezes, e as inserções válidas são cinco.

Gabarito: letra C

Link permanente: /questoes/fg165212