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:
Aforam inseridas 6 (seis) linhas e o número final para sq_empresa_pk.CURRVAL é igual a 6 (seis);
Bnenhuma linha pode ser inserida e o número final para sq_empresa_pk.CURRVAL é igual a 2 (dois);
Cforam inseridas 5 (cinco) linhas e o número final para sq_empresa_pk.CURRVAL é igual a 6 (seis);
Dforam inseridas 5 (cinco) linhas e o número final para sq_empresa_pk.CURRVAL é igual a 4 (quatro);
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:
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.
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.
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.
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.
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.
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.