Resumão de PL/SQL, parte 4: controles condicionais e seqüenciais

A PL/SQL conta com as seguintes estruturas de controle:

  • Controle condicional
    • IF-THEN-ELSIF-ELSE
    • CASE
      • CASE statements
        • Simple CASE statements
        • Searched CASE statements
      • CASE expressions
        • Simple CASE expressions
        • Searched CASE expressions
  • Controle seqüencial
    • GOTO
    • NULL

1) IF-THEN-ELSIF-ELSE

A sintaxe geral do controle condicional por IF, é a seguinte:

IF condição THEN
  comandos;

[ELSIF condição THEN
  comandos;]

[ELSE
  comandos;]

END IF;

Na sintaxe acima, condição é uma expressão booleana que pode retornar TRUE, FALSE ou NULL. O bloco de código só executa se a condição for TRUE. Devemos ter cuidado para tratar condições que avaliam para NULL, ou seja: para cada variável ou coluna que referenciamos em uma expressão booleana, devemos pensar sobre o que fazer se o resultado for NULL!

As condições especificadas no IF e no ELSIF devem ser mutuamente exclusivas (isso não é obrigatório, mas evita bugs e confusões no código) e podemos aninhar várias instruções IF-THEN-ELSIF-ELSE.

É importante lembrar que a PL/SQL avalia as expressões de modo “curto”, ou seja, ela não precisa avaliar toda a expressão condicional se, ao avaliar apenas uma parte, ela já determina que a condição será TRUE ou FALSE. Esse comportamento é util para melhorar a performance do código: coloque as condições que impliquem em maior utilização de CPU ou memória no final da expressão (ou use um IF aninhado onde o IF externo avalia a condição de menor custo e, se ela é verdadeira, o IF interno avalia a condição de maior custo).

2) CASE

2.1) CASE statements

O CASE permite que selecionemos uma de muitas condições possíveis para ser executada. Existem 2 tipos de CASE statements: simple e searched.

O SIMPLE CASE STATEMENT avalia o resultado de 1 única expressão e executa uma de muitas condições baseadas no resultado dessa única expressão:

CASE expressão

  WHEN resultado THEN comandos ;

  [WHEN resultadoN THEN comandos ;]

  [ELSE comandos ;]

END CASE;

A expressão e os resultados podem ser valores escalares ou expressões que avaliam para valores escalares (mas a expressão continua sendo 1 única), por exemplo:

begin
  case true
    when ( (1 = 1) and (1 > 2) ) then dbms_output.put_line('a');
    when ( (1 < 2) and null ) then dbms_output.put_line('b');
    else dbms_output.put_line('c');
  end case;
end;

ATENÇÃO: a cláusula ELSE pode ou não ser obrigatória na simple case statement: se os resultados listarem TODOS os resultados possíveis da expressão, então a ELSE não é obrigatória; mas se os resultados não listarem todos os resultados possíveis da expressão e a expressão avaliar para um resultado não listado, a ELSE é obrigatória, caso contrário a PL/SQL levanta uma exception de CASE_NOT_FOUND. Teste isso com o código abaixo:

begin
  case 1
    when 2 then dbms_output.put_line('2');
    when 3 then dbms_output.put_line('3');
  end case;
end;

A SEARCHED CASE STATEMENT avalia o resultado de múltiplas expressões booleanas e executa os comandos da primeira que resulta TRUE:

CASE

  WHEN expressão_booleana THEN comandos ;

  [WHEN expressão_booleanaN THEN comandos ;]

  [ELSE comandos ;]

END CASE;

O ELSE é opcional ou obrigatório dependendo se pelo menos uma expressão avalia para TRUE. Nesse caso o ELSE é opcional. Mas se nenhuma expressão avaliar para TRUE, o ELSE é obrigatório (caso contrário ocorre o erro CASE_NOT_FOUND). Teste isso com:

begin
  case
    when 1 between 2 and 3 then dbms_output.put_line('a');
    when 2 between 3 and 4 then dbms_output.put_line('b');
  end case;
end;

Da mesma forma que o IF-THEN-ELSIF-ELSE, as expressões na CASE devem ser mutuamente exclusivas (não obrigatório, mas importante para evitar bugs) e várias CASE podem ser aninhadas. Lembre-se também do modo de avaliação “curto” da PL/SQL e coloque as expressões mais freqüentes e/ou de menor utilização de CPU entre as primeiras opções.

Qual escolher, a SIMPLE ou a SEARCHED case statements? Usamos a SIMPLE CASE STATEMENT quando queremos que a decisão tenha como base o resultado de 1 única expressão; usamos a SEARCHED CASE STATEMENT quando queremos usar várias expressões booleanas que podem avaliar para TRUE, FALSE ou NULL.

2.2) CASE expressions

Agora a coisa fica um pouco confusa: as CASE EXPRESSION são quase a mesma coisa das case statements, mas são usadas para substituir expressões na SQL e na PL/SQL e retornar um valor. Por exemplo, estude os exemplos abaixo:

select case 1
         when 2 then 'a'
         when 3 then 'b'
         else 'c'
       end as teste
from dual;



declare
  v_teste varchar2(10) := null;
begin
  v_teste := case 'azul'
              when 'vermelho' then 'errado'
              when 'verde'    then 'errado'
              when 'azul'     then 'certo'
              else 'não sei'
             end
             ;
  dbms_output.put_line(v_teste);
end;



select case
         when ('azul' = 'vermelho') then 'doido'
         when ('azul' = 'verde')    then 'doido'
         when ('azul' = 'azul')     then 'normal'
       end as teste
from dual;



declare
  v_teste varchar2(10) := null;
begin
  v_teste := case
              when ('azul' = 'vermelho') then 'doido'
              when ('azul' = 'verde')    then 'doido'
              when ('azul' = 'azul')     then 'normal'
              else 'não sei'
             end
             ;
  dbms_output.put_line(v_teste);
end

Note que as CASE EXPRESSIONS, tanto as SIMPLE CASE EXPRESSION quanto as SEARCHED CASE EXPRESSION, são usadas para substituir uma expressão em SQL ou em PL/SQL e retornar um único resultado para a expressão.

ATENÇÃO: as CASE EXPRESSION são terminadas por “END” e não por “END CASE”. Além disso, NÃO USAMOS o ponto-e-vírgula (;) nas CASE EXPRESSION, nem após o END final.

Por fim, o ELSE nas CASE EXPRESSION, diferentemente das CASE STATEMENT, é sempre opcional: se nenhuma situação das CASE EXPRESSION retornar o valor desejado e não existir um ELSE, a CASE EXPRESSION retorna NULL (não dá o erro de CASE_NOT_FOUND).

Somente como uma ilustração entre a diferança das case STATEMENT para as case EXPRESSION, veja um exemplo de CASE EXPRESSION usada para fornecer o resultado da expressão de uma CASE STATEMENT (estude as diferenças de sintaxe):

BEGIN
  CASE (CASE 1
          WHEN 1 THEN 'a'
          WHEN 2 THEN 'b'
          WHEN 3 THEN 'c'
        END)
    WHEN 'a' THEN dbms_output.put_line('O resultado é:');
                  dbms_output.put_line(1);
    WHEN 'b' THEN dbms_output.put_line('O resultado é:');
                  dbms_output.put_line(2);
    WHEN 'c' THEN dbms_output.put_line('O resultado é:');
                  dbms_output.put_line(3);
    ELSE dbms_output.put_line('O resultado é:');
         dbms_output.put_line('Desconhecido');
  END CASE;
END;

3) GOTO

O GOTO é um tipo de controle seqüencial, ou seja, não-condicional. Ele informa para a PL/SQL seguir incondicionalmente para outra parte do código no bloco. Sua sintaxe é simples:

GOTO label ;

O label é o identificador de um label de código definido por:

<<nome_do_label>>

Ao usar o GOTO, a PL/SQL executa os comandos imediatamente após o label.

O uso do GOTO pode ser útil, mas é extremamente raro. Obs.: deve existir obrigatóriamente um comando executável após o label (mesmo que seja o controle NULL).

4) NULL

O NULL é outro tipo de controle seqüencial (não-condicional) e serve para informar à PL/SQL para não fazer absolutamente nada. A sintaxe é:

NULL;

Ele é usado, basicamente, para: melhorar a legibilidade do código; evitar a execução de comandos adicionais; pular várias checagens de validação quando uma falha.

4 thoughts on “Resumão de PL/SQL, parte 4: controles condicionais e seqüenciais”

  1. Pingback: bahis siteleri
  2. Pingback: bahis siteleri
  3. Pingback: bahis siteleri
  4. Pingback: sportotobet

Leave a Reply