PL/SQL o que?
PL/SQL é uma linguagem de programação para o banco de dados (e algumas outras aplicações) da Oracle. Permite que você manipule os dados de forma procedural ou em blocos, o que não é possível usando puramente SQL padrão ANSI.
Para quem tem um desenvolvedor inquieto dentro de si, significa a liberdade de programar repetições (for, while, loop), programar condições (if, case), trabalhar com variáveis e essa coisa toda, no banco de dados.
Assim, pode-se ter boa parte do código de uma aplicação embutida no banco, trazendo vários benefícios, principalmente em relação a performance e segurança.
O Bloco Anônimo
Não é (ainda) um grupo de carnavalescos foliões que seguem um trio elétrico (mas bora criar um pros DBAs nerds pularem carnaval?).
Um código PL/SQL pode ser armazenado como um objeto dentro do banco de dados. Seriam as famosas Procedures, Functions e Triggers. Esses objetos podem ainda ser agrupados em Packages (pacotes), para facilitar a lógica e o gerenciamento de um grupo de blocos que possuem relacionamento entre si ou compartilham fatores em comum.
Eventualmente, podemos sentir a necessidade de executar um código PL/SQL singular, apenas uma vez, para algum teste ou para uma correção de um dado, por exemplo. Nesses casos (e em outros que julgar necessário) você pode usar um bloco anônimo. É um bloco PL/SQL que não será armazenado definitivamente no banco. O bloco será interpretado, executado e depois será descartado.
Não use bloco anônimo se você sentir que irá executar ou já estiver executando o mesmo bloco mais de uma vez, mesmo que a frequência esteja mais para semanal ou mensal do que diária. Nesse caso é melhor criar uma Procedure, pois o Oracle poderá (dependendo do cenário) utilizar recursos internos para obter melhor performance ao executar o mesmo código várias vezes quando ele está armazenado no banco.
Estrutura do Bloco Anônimo
[DECLARE]
BEGIN
-- Statements
[EXCEPTION]
END;
/
Exemplos
-- Bloco Anonimo #1 --
-- Exibe o dia da semana da data corrente --
BEGIN
DBMS_OUTPUT.PUT_LINE('Output:' || CHR(10) || TO_CHAR(SYSDATE,'DAY'));
END;
/
-- Bloco Anonimo #2 --
-- Exibe a data e hora correntes --
BEGIN
DBMS_OUTPUT.PUT_LINE ('Output:' || CHR(10) || TO_CHAR(SYSDATE, 'DD/MON/YYYY hh24:mm'));
END;
/
-- Bloco Anonimo #3 --
-- Exibe dados de um funcionario da tabela 'employees', schema 'hr' --
DECLARE
v_emp hr.employees%ROWTYPE;
BEGIN
SELECT * INTO v_emp
FROM hr.employees
WHERE employee_id=&emp_id;
DBMS_OUTPUT.PUT_LINE('-----------------------------------');
DBMS_OUTPUT.PUT_LINE('ID: ' || TO_CHAR(v_emp.employee_id));
DBMS_OUTPUT.PUT_LINE('Nome: ' || TO_CHAR(v_emp.first_name));
DBMS_OUTPUT.PUT_LINE('Sobrenome: ' || TO_CHAR(v_emp.last_name));
DBMS_OUTPUT.PUT_LINE('-----------------------------------');
END;
Executando Blocos Anônimos – Dicas
Muito comum na vida de um DBA é pegar um script oriundo de outro time (que muitas vezes é até de outra empresa), normalmente desenvolvedores que cuidam das aplicações, e ter que executar esse script em alguma das suas instâncias de banco de dados.
Esse tópico vale um post só pra ele, dicas sobre execução de scripts: “Executando scripts – Dicas“.
Além de atentar para as dicas gerais de execução de script no link acima, quando vamos executar um bloco PL/SQL que outra pessoa programou, é sempre bom observar se o caractere de término do bloco anônimo (essa barra: ‘/’) consta no final do script. Isso costuma causar confusões.
Já me pediram ajuda mais de uma vez para saber porque a execução de um bloco estava demorando para terminar. O problema é que a execução nem tinha iniciado! =P
Muitas vezes o autor do código esquece de colocar o caractere terminador: ‘/’. Então, o seu cursor no prompt fica parado esperando nova instrução, ele não sabe que já pode executar o que foi digitado. Mesmo que você dê vários [ENTER], ele continua aguardando novas instruções e parece que fica naquele estado onde não libera seu cursor. Por parecer um comportamento típico de quando há algo executando em segundo plano, muitas vezes acham que o script já está executando e, na verdade, não está.
Fui perguntado, certa vez:
- Mas já tem um “END;” no final do bloco. Por que, POR QUE, MEU DEUS, tenho que colocar a barra???
Resposta:
Sem o caractere ‘/’ pode significar que aquele bloco ainda não está terminado. É possível, após um “END;”, termos outras instruções PL/SQL para serem executadas, um bloco PL/SQL dentro de outro. Por isso o Oracle não irá executar nada do bloco até receber o terminador barra.
-- Exemplo de bloco dentro de outro bloco --
BEGIN
DBMS_OUTPUT.PUT_LINE('Bloco Anonimo Principal - Checkpoint 1');
BEGIN
DBMS_OUTPUT.PUT_LINE('Bloco Anonimo Interno 1 - Checkpoint 2');
END;
DBMS_OUTPUT.PUT_LINE('Bloco Anonimo Principal - Checkpoint 3');
BEGIN
DBMS_OUTPUT.PUT_LINE('Bloco Anonimo Interno 2 - Checkpoint 4');
END;
DBMS_OUTPUT.PUT_LINE('Bloco Anonimo Principal - Checkpoint 5');
END;
/
Se o código, após o [ENTER] depois do primeiro “END;”, no exemplo acima, fosse executado, estaria errado e retornaria erro. O código não estava completo, não era para executar. Se ainda não ficou claro, segue uma analogia para o significado do ‘/’:
Dear Oracle, Master of all Databases, I’m done writing down my prayers to you. Please read it, execute it and report me any problems, my Lord. Sincerely, Your cleric, DBA.
Se você escrever isso e der [ENTER] também funciona, juro!