Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — FUNDATEC 2023

Banco de DadosConsultas e Comandos em SQL
Código
qa537506
Banca
FUNDATEC
Órgão
BRDE
Ano
2023
Cargo
Ana Sist ( )

Considere as tabelas criadas com os comandos SQL abaixo, e os comandos de inserção de tuplas SQL (padrão SQL99 ou superior).

 

Create table A (pka int primary key, a1 integer);

Create table B (pkb int primary key, b1 integer);

Create table C (pkc int primary key, c1 integer);

insert into A values (1,10);

insert into A values (2, 10);

insert into A values (3, 2);

insert into A values (4, 3);

insert into B values (10,0);

insert into C values (100,0);

 

Suponha a criação dos gatilhos T1 e T2 definidos abaixo cujas cláusulas estão de acordo com padrão, e cujo código disparado foi escrito conforme sintaxe PL/SQL (Oracle).

 

Create Trigger T1

Before delete on A

begin

    Update B set b1 = b1 + 1;

end;

Create Trigger T2

After delete on A

for each row

begin

    Update C set c1 = c1 + 1;

end;

 

Considere que os três comandos SQL de remoção de tuplas abaixo foram executados sem erro:

 

I. delete from A where a1>=10;

 

II. delete from A where a1<10;

 

III. delete from A where a1 is null;

 

Finalmente, foram executadas as duas consultas SQL abaixo, cada qual retornando uma única tupla:

 

(1) SELECT b1 FROM B;

 

(2) SELECT c1 FROM C;

 

Selecione a alternativa que representa, nesta ordem, o valor do atributo b1 resultante da consulta (1), e o valor do atributo c1 resultante da consulta (2).

  1. A2 – 2.
  2. B2 – 3.
  3. C2 – 4.
  4. D3 – 2.
  5. E3 – 4.
Revelar gabarito e comentário

GabaritoE — 3 – 4.

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

Gatilhos (Triggers) em SQL: escopo de execução e efeito acumulado

Gabarito: letra E. O gatilho T1, definido como BEFORE DELETE sem a cláusula FOR EACH ROW, é um gatilho de nível de instrução e dispara uma única vez por comando DELETE, independentemente do número de linhas afetadas. Já o gatilho T2, definido como AFTER DELETE ... FOR EACH ROW, é um gatilho de nível de linha e dispara uma vez para cada linha removida. Como o comando I remove 2 linhas, o comando II remove 2 linhas e o comando III remove 0 linhas, o total de disparos de T1 é 3 (um por comando) e o de T2 é 4 (2+2+0). Assim, b1 = 0 + 3 = 3 e c1 = 0 + 4 = 4.

A questão exige compreender a diferença fundamental entre gatilhos de nível de instrução e de nível de linha. Um gatilho de nível de instrução (BEFORE DELETE ou AFTER DELETE sem FOR EACH ROW) executa seu corpo uma única vez para a instrução SQL inteira, não importando quantas tuplas são afetadas. Já um gatilho de nível de linha (FOR EACH ROW) executa o corpo uma vez para cada tupla afetada pela instrução. Essa distinção é crucial para prever o efeito acumulado de comandos de modificação em massa.

Vamos analisar o estado inicial das tabelas e o efeito de cada comando DELETE:

  • Tabela A: contém as tuplas (1,10), (2,10), (3,2) e (4,3).

  • Tabela B: contém a tupla (10,0), então b1 = 0.

  • Tabela C: contém a tupla (100,0), então c1 = 0.

Comando I: DELETE FROM A WHERE a1>=10; — Remove as tuplas com a1 maior ou igual a 10. Na tabela A, as tuplas (1,10) e (2,10) atendem à condição. Portanto, 2 linhas são removidas. O gatilho T1 (nível de instrução) dispara 1 vez, incrementando b1 para 1. O gatilho T2 (nível de linha) dispara 2 vezes (uma para cada linha removida), incrementando c1 para 2.

Comando II: DELETE FROM A WHERE a1<10; — Remove as tuplas com a1 menor que 10. As tuplas (3,2) e (4,3) atendem à condição. Portanto, 2 linhas são removidas. O gatilho T1 dispara 1 vez, incrementando b1 para 2. O gatilho T2 dispara 2 vezes, incrementando c1 para 4.

Comando III: DELETE FROM A WHERE a1 is null; — Remove as tuplas onde a1 é NULL. Como nenhuma tupla na tabela A tem a1 NULL, 0 linhas são removidas. O gatilho T1 dispara 1 vez (mesmo sem linhas afetadas, o comando é executado), incrementando b1 para 3. O gatilho T2 dispara 0 vezes, pois não há linhas para iterar, mantendo c1 em 4.

A pegadinha central está em dois pontos: (1) o gatilho de nível de instrução T1 dispara mesmo quando o DELETE não remove nenhuma linha, pois ele é executado antes da operação, independentemente do resultado; (2) o gatilho de nível de linha T2 só dispara para linhas efetivamente removidas. Muitos candidatos erram ao contar o número de disparos de T1 como se fosse por linha, ou ao ignorar o disparo de T1 no comando III.

Guarde a distinção entre nível de instrução (uma vez por comando) e nível de linha (uma vez por tupla afetada) — é exatamente nela que as alternativas se dividem.

Alternativa A — ❌ Incorreta

Afirma que b1 = 2 e c1 = 2. O valor de b1 está incorreto, pois o gatilho T1 dispara 3 vezes (uma por comando DELETE), resultando em b1 = 3. O valor de c1 também está incorreto, pois o gatilho T2 dispara 4 vezes (2+2+0), resultando em c1 = 4. A alternativa subestima ambos os contadores, provavelmente por considerar apenas os comandos I e II, ignorando o disparo de T1 no comando III e contando T2 apenas para as linhas efetivamente removidas nos dois primeiros comandos.

Alternativa B — ❌ Incorreta

Afirma que b1 = 2 e c1 = 3. O valor de b1 está incorreto (deveria ser 3, pois T1 dispara 3 vezes). O valor de c1 também está incorreto (deveria ser 4, pois T2 dispara 4 vezes). A alternativa parece contar T1 apenas para os comandos I e II (ignorando o comando III) e T2 como 2+1, o que não corresponde a nenhuma lógica de disparo correta.

Alternativa C — ❌ Incorreta

Afirma que b1 = 2 e c1 = 4. O valor de b1 está incorreto (deveria ser 3). O valor de c1 está correto (4). A alternativa acerta o valor de c1, mas erra o de b1, provavelmente por ignorar o disparo de T1 no comando III, que não remove nenhuma linha, mas ainda assim executa o gatilho de nível de instrução.

Alternativa D — ❌ Incorreta

Afirma que b1 = 3 e c1 = 2. O valor de b1 está correto (3). O valor de c1 está incorreto (deveria ser 4). A alternativa acerta o valor de b1, mas erra o de c1, provavelmente por contar T2 apenas para o comando I (2 disparos) e ignorar os disparos do comando II, ou por considerar que T2 dispara apenas uma vez por comando, o que é incorreto para um gatilho de nível de linha.

Alternativa E — ✅ Correta ⟵ GABARITO

Afirma que b1 = 3 e c1 = 4. O valor de b1 = 3 está correto, pois o gatilho T1, de nível de instrução, dispara uma vez para cada comando DELETE (I, II e III), totalizando 3 incrementos. O valor de c1 = 4 está correto, pois o gatilho T2, de nível de linha, dispara uma vez para cada linha removida: 2 linhas no comando I + 2 linhas no comando II + 0 linhas no comando III = 4 disparos. A alternativa reflete corretamente a diferença entre os dois tipos de gatilho.

A regra de ouro para questões de gatilhos é identificar o escopo: FOR EACH ROW significa que o gatilho executa para cada linha afetada, enquanto sua ausência significa que ele executa uma única vez por instrução. No comando III, mesmo sem linhas removidas, o gatilho de nível de instrução T1 ainda é executado, pois ele é disparado antes da operação de exclusão, independentemente do resultado.

Gabarito: letra E

Link permanente: /questoes/qa537506