apostila plsql

Upload: adriano-ramos

Post on 30-Oct-2015

350 views

Category:

Documents


1 download

TRANSCRIPT

  • APOSTILA DE

    ORACLE PL/SQL

  • PL/SQL A linguagem PL/SQL (Procedural Language/SQL) uma extenso de linguagem procedural da Oracle para SQL, que incorpora recursos de programao, tais como:

    Declarao de variveis e tipos pr-definidos; Estruturas de seleo e repetio;

    Procedimentos e funes.

    Alm de aceitar a manipulao de dados, ela tambm permite que as instrues de consulta da linguagem SQL sejam includas em unidades procedurais de cdigo e estruturadas em blocos, tor-nando a linguagem SQL uma linguagem avanada de processamento de transaes. A linguagem PL/SQL estruturada em blocos, os programas podem ser divididos em blocos lgi-cos. Um bloco PL/SQL dividido em trs sees:

    DECLARATIVA (opcional) - Seo destinada declarao das variveis, cursores e exce-es que sero utilizadas no bloco; EXECUTVEL (obrigatria) - tambm conhecida como corpo do programa, rea onde so descritos os passos necessrios para realizao da tarefa. Podem ser utilizadas instrues SQL e/ou PL/SQL; TRATAMENTO DE EXCEES (opcional) - destinada ao tratamento das excees gera-das no bloco; devem ser descritas as aes a serem desempenhadas quando ocorrerem erros.

    1.1. Blocos Annimos Os blocos annimos no ficam armazenados na base de dados e no podem ser chamados por outros blocos PL/SQL. Eles devem ser compilados a cada utilizao. Pode-se incorporar um bloco annimo em uma aplicao ou pode-se execut-lo interativamente no SQL*Plus. Exemplo da estrutura de um bloco em PL/SQL: DECLARE

    v_variavel varchar2(5); BEGIN

    Select nome_coluna into v_variavel from

    EXCEPTION nome_tabela;

    When then ... (procedimentos a serem executados quando uma determinada exceo correr.) o

    END; Sobre o cdigo:

    As palavras chave DECLARE, BEGIN e EXCEPTION no so sucedidas de ponto e vrgula (;), apenas as demais instrues;

    A palavras-chave BEGIN e END so obrigatrias.

    Deve-se utilizar uma barra (/) para executar o bloco annimo PL/SQL no buffer do S-

    QL*Plus.

  • 1.1.1. Operadores e delimitadores Operador Descrio Operador Descrio

    + Adio % Atributo * Multiplicao . Separador de componentes - Subtrao Cadeia de caracteres / Diviso : Varivel de ligao ** Exponenciao := Atribuio || Concatenao .. Intervalo = Igualdade -- Comentrio de linha > Comparao maior que > Delimitador de final do texto do label (etiqueta)

    >= Comparao maior ou igual ; Finalizador de instruo

  • 1.1.3. Tipos de Variveis Todas as variveis PL/SQL tm um tipo de dados que especifica o formato de armazenamento, restries e uma faixa vlida de valores. A linguagem PL/SQL suporta quatro categorias destes:

    Escalares - armazenam um nico valor. Os principais tipos de dados so aqueles que cor-respondem aos tipos de coluna nas tabelas do Oracle Server, por exemplo vachar2, num-ber, char, entre outros; a linguagem PL/SQL tambm suporta variveis booleanas; Compostos comporta o armazenamento de diferentes valores. Os tipos compostos em PL/SQL so registro, tabelas e matrizes; Referenciais - armazenam valores, chamados de indicadores, que designam outros itens de programa. Um exemplo de tipos referenciais o REF CURSOR.

    Declarao de Variveis Sintaxe:

    identificador [CONSTANT] tipo de dados [NOT NULL] [:= valor para inicializao | expr default]

    onde,

    Identificador: o nome da varivel; Os identificadores no devem ter mais de 30 carac-teres. O primeiro caracter deve ser uma letra; os demais podem ser letras, nmeros ou smbolos especiais; No devem ser palavras reservadas nem possuir espaos entre os caracteres.

    CONSTANT: restringe as variveis para que o seu valor no possa ser alterado; as

    constantes devem ser inicializadas tipo de dados so tipos de dados escalares, compostos, referenciais ou LOB NOT NULL indica preenchimento obrigatrio (variveis NOT NULL devem ser iniciali-

    zadas). expr uma expresso PL/SQL que pode ser uma literal, uma outra varivel ou

    uma expresso que envolve operadores e funes. ATENO:

    Para inicializar a varivel utiliza-se operador de atribuio (:=) ou a palavra reservada DE-FAULT. Se no for atribudo um valor inicial, a nova varivel conter NULL por default.

    No aconselhvel identificar uma varivel com nome igual ao nome das colunas de ta-bela usadas no bloco. Se as variveis PL/SQL ocorrerem nas instrues SQL e tiverem o mesmo nome que uma coluna, o Oracle Server supe que a coluna que est sendo refe-renciada.

    1.1.3.1 Tipos de Dados Escalares Um tipo de dado escalar armazena um valor nico e no possui componentes internos. Os tipos de dados escalares podem ser classificados em quatro categorias: nmero, caractere, data e boo-leano. Os tipos de dados de caractere e nmero possuem subtipos que associam um tipo bsico a uma restrio. Por exemplo, INTEGER e POSITIVE so subtipos do tipo bsico NUMBER. Segue abaixo exemplo de tipos de Dados Escalares Bsicos:

  • Tipo de dado Descrio VARCHAR2(tamanho) Caracteres com tamanho varivel com at 32.767 bytes; no h

    tamanho default para estas variveis. NUMBER(tamanho, preciso) Nmeros reais ou inteiros DATE Datas e horas entre os perodos de 4712 A.C. e 9999 D.C. CHAR(tamanho) Caracteres de tamanho fixo at 32.767 bytes; tamanho default 1

    byte. LONG Caracteres com tamanho varivel de at 32.760 bytes, a largura

    mxima de 2.147.483.647 bytes LONG RAW Dados binrios e strings de byte de at 32.760 bytes; estes da-

    dos no so interpretados pelo PL/SQL BOOLEAN Um de trs possveis valores: TRUE, FALSE ou NULL BINARY_INTEGER Nmeros inteiros entre 2.147.483.647 e 2.147.483.647 PLS_INTEGER Nmeros inteiros entre 2.147.483.647 e 2.147.483.647; estes

    valores requerem menos armazenamento e so mais rpidos que os valores NUMBER e BINARY_INTEGER

    Exemplos:

    v_nascimento date; v_data date := sysdate + 7; --declarao de varivel e inicializao partir de uma operao aritmtica

    v_codigo number(2) not null := 10; -- declarao da varivel com a restrio de preenchimento obrigatrio, neste caso preciso atribuir o valor inicial v_UF varchar2(2) := SP; -- declarao e inicializao da varivel com o valor SP; observe que os literais devem ser informados entre apstrofos ( ) v_Loc varchar2(2) default RJ; -- declarao da varivel cujo valor efault RJ. d

    v_teste_logico boolean := (v_valor1 < v_valor2); -- declarao da varivel v_teste_logico que ser inicializada com o resultado da xpresso (v_valor1 < v_valor2) e

    c_const constant number := 54; -- declarao da constante que est sendo inicializada.

    O atributo %TYPE pode ser utilizado para declarar variveis com a mesma estrutura de uma tabela ou de uma varivel j existente. Sintaxe:

    identificador [CONSTANT] {tabela.coluna%type | variavel%type} [NOT NULL] [:= valor para inicializao | expr default]

    Exemplos:

    v_nome EMPR_NOME_DS%type; -- declarao da varivel com a mesma estrutura da coluna EMPR_NOME_DS da tabela EMPR. v_balance number(7,2); v_min_balance v_balance%type; -- declarao da varivel com a mesma estrutura da varivel declarada anteriormente.

  • ATENO: uma boa prtica de programao a adoo de uma conveno de nomeao para variveis, por expl: o prefixo v_ representa uma varivel; c_ representa uma constante.

    1.1.4. Variveis de Substituio Alm das variveis declaradas no Bloco PL/SQL existem as variveis de substituio e de ligao. O cdigo PL/SQL no tem capacidade de entrada/sada prpria, para isso pode-se utilizar o ambi-ente no qual o cdigo PL/SQL estiver sendo executado para passar valores para o bloco, estes va-lores so passados por meio das variveis de substituio. ATENO: Ao utilizar as variveis de substituio os valores so substitudos no bloco PL/SQL antes que esse bloco seja executado. Por isso, no possvel substituir os diferentes valores para as variveis de substituio usando um loop. Exemplo:

    ACCEPT p_nome PROMPT Digite o nome do funcionrio... ACCEPT p_sal_mes PROMPT Digite o valor do salario...

    O comando accept indica que o valor para a varivel de substituio p_nome e p_sal_mes sero fornecidos pelo teclado. O comando PROMPT indica a mensagem que ser exibida para orientar o usurio quanto ao valor a ser digitado. Para atribuir os valores das variveis de substituio para as variveis PL/SQL necessrio a utilizao do & (E comercial). Exemplo:

    Declare v_nome varchar2(30) := &p_nome; v_sal number(9,2) := &p_sal_mes;

    1.1.5. Variveis de ligao Para declarar uma varivel de ligao no ambiente SQL*Plus, utiliza-se o comando VARIABLE. Exemplo:

    SQL> VARIABLE g_sal_anual NUMBER

    Estas variveis podem ser declaradas no prompt do SQL ou fora do bloco PL/SQL (antes do declare ou depois da /). Para utilizar estas variveis no bloco PL/ SQL deve-se preced-las de : (dois pontos), para que sejam distinguidas das variveis PL/SQL: Exemplo:

    :g_sal_anual := v_sal * 12;

    A exibio dos valores armazenados nestas variveis pode ser feita por meio do comando PRINT. Exemplo:

    PRINT g_sal_anual

    Exemplo 1: Calcular o salrio anual de dado funcionrio com base no salrio mensal fornecido pe-lo usurio. Exibir o resultado.

  • VARIABLE g_sal_anual NUMBER ACCEPT p_nome PROMPT Nome do funcionario...: ACCEPT p_sal_mes PROMPT Valor do salario...:

    Instruo SQL

    Declare v_nome varchar2(30) := &p_nome; v_sal number(9,2) := &p_sal_mes; Begin :g_sal_anual := v_sal * 12; END; /

    Bloco PL/SQL

    PRINT g_sal_annual Instruo SQL Para testar o exemplo 1: Escreva o cdigo utilizando um editor de textos; salve o arquivo com a extenso .sql (p.expl.: e-xemplo1.sql); no prompt do Sql*Plus digite: @localizao do arquivo\nome do arquivo, por exem-plo:

    SQL>@C:\programas\exemplo1.sql

    No exemplo 1 foi utilizado o comando PRINT para exibio do resultado do processamento. Uma outra opo para isso a utilizao do pacote DBMS_output e procedimento put_line. Sintaxe:

    DBMS_output.put_line(mensagem);

    onde mensagem pode ser: uma cadeia de caracteres, por exemplo: DBMS_output.put_line (O nome do funcionrio ); e

    neste caso dever ser especificada entre apstrofos. uma varivel ou constante, por exemplo: DBMS_output.put_line (v_sal_anual); ou ambas, por exemplo: DBMS_output.put_line(nome do funcionrio || v_sal_anual);

    utilizando o operador de concatenao || para unir as duas mensagens. ATENO: Para a utilizao deste pacote necessrio ativ-lo no SQL*Plus por meio da instru-o SET SERVEROUTPUT ON. Exemplo 2: Calcular o salrio anual de dado funcionrio com base no salrio mensal fornecido pe-lo usurio. Exibir o resultado. SET SERVEROUTPUT ON ACCEPT p_nome PROMPT Digite o nome do funcionrio... ACCEPT p_sal_mes PROMPT Digite o valor do salario...

    Instruo SQL

    Declare v_nome varchar2(30) := &p_nome; v_sal number(9,2) := &p_sal_mes; v_sal_anual number(9,2); Begin v_sal_anual := v_sal * 12; DBMS_output.put_line(O salario anual de || END;

    v_nome || || v_sal_anual);

    /

    Bloco PL/SQL

    No exemplo 2 no est sendo utilizada a varivel de ligao g_sal_anual, pois a solicitao da exi-bio do resultado do processamento est sendo feita na rea executvel do bloco PL/SQL.

  • 1.1.6. Instrues SELECT em PL/SQL Recuperar dados do banco de dados com a instruo SELECT. Sintaxe:

    SELECT colunas INTO {variveis...| registro} FROM tabela WHERE condio;

    onde, colunas: lista de colunas que retornaro dados consulta; podem incluir funes de

    linhas, de grupo ou expresses SQL Into: clusula obrigatria, usada para especificar os nomes das variveis que ar-

    mazenaro os valores que o SQL retornar a partir da clusula SELECT. Deve-se oferecer uma varivel para cada coluna, seguindo a mesma ordem.

    Variveis: nome das varivies que iro armazenar o valor recuperado Registro: o registro PL/SQL para armazenar os valores recuperados Tabela: especifica o nome da tabela do banco de dados Condio: composta de nomes de coluna, expresses, constantes e operadores de

    comparao, incluindo as variveis PL/SQL e operadores.

    Exemplo 3: Recuperar o nome e o cargo do funcionrio para o cdigo indicado.

    VARIABLE g_nome varchar2(15) VARIABLE g_cargo varchar2(15) DECLARE

    v_nome EMP.EMPR_NOME_DS%type; v_cargo EMP.EMPR_SERV_DS%type;

    BEGIN select EMPR_NOME_DS, EMPR_SERV_DS into v_nome, v_cargo from EMPR where EMPR_NUME_NR = 7934;

    :g_nome := v_nome; END;

    :g_cargo := v_cargo;

    / PRINT g_nome PRINT g_cargo

    ATENO: As instrues SELECT em um bloco PL/SQL as consultas devem retornar apenas uma linha, mais de uma ou nenhuma linha geram mensagens de erro que poder ser tratado. Para consultas que retornam vrias linhas dever ser criado um cursores explcitos, que sero vistos a-diante. Exemplo 4: Calcular e exibir a somatria do salrio de todos os funcionrios de um dado depar-tamento.

    SET SERVEOUTPUT ON DECLARE

    v_soma_sal EMPR_SALA_VL%TYPE; v_deptno NUMBER NOT NULL := 10;

    BEGIN SELECT SUM(sal) INTO v_soma_sal FROM empr WHERE deptno = v_deptno;

  • DBMS_output.put_line(A soma dos salrios do departamento || v_deptno || || v_soma_sal);

    END;

    1.1.7. Aninhamento de blocos e Escopo das variveis As variveis podem ser utilizadas em determinadas reas do programa, um bloco PL/SQL pode ser composto por vrios blocos aninhados (sub-blocos), cada sub-bloco pode possuir suas vari-veis. No exemplo 5 a varivel valor1 declarada nos 3 sub-blocos que compe o programa, mas em cada bloco o seu valor preservado e no gerado nenhum tipo de conflito pois estas vari-veis so locais. Exemplo 5: Aninhamento de blocos e escopo de variveis

    SET SERVEROUTPUT ON DECLARE -- bloco 1

    valor1 number(2) := 7; valor2 number(2) := 13;

    BEGIN -- bloco 1 DECLARE -- bloco 2

    valor1 varchar2(30) := 'Valor 1 do bloco 2'; BEGIN -- bloco 2

    DECLARE -- bloco 3 valor1 date := sysdate;

    BEGIN -- bloco 3 DBMS_OUTPUT.PUT_LINE('Valor 1 do bloco 3...' || valor1);

    END; -- bloco 3 DBMS_OUTPUT.PUT_LINE('Valor 1 do bloco 2...' || valor1);

    END; -- bloco 2 DBMS_OUTPUT.PUT_LINE('Valor 1 do bloco 1... ' || valor1);

    END; -- bloco 1 /

    Resultado da execuo do bloco: SQL> @c:\programas\escopo.sql Valor 1 do bloco 3...12/05/04 Valor 1 do bloco 2...Valor 1 do bloco 2 Valor 1 do bloco 1... 7

    1.1.8. Insero de Dados Exemplo 6: Adicionar informaes sobre novos funcionrios na tabela EMPR.

    DECLARE

    v_ename EMPR_NOME_DS%type := 'ZE TONHAO'; v_job EMP.EMPR_SERV_DS%type := 'BALCONISTA'; v_deptno EMPR.DEPT_NUME_NR%type := 30;

    BEGIN Insert into EMPR (EMPR_NUME_NR, EMPR_NOME_DS, EMPR_SERV_DS, DEPT_NUME_NR) values (v_empno, v_ename, v_job, v_deptno);

    END;

  • 1.1.9. Atualizando Dados Exemplo 7: Aumentar o salrio de todos os funcionrios na tabela EMPR e que sejam Analistas, adicionando 2000 ao valor do salrio.

    DECLARE v_sal_increase empr_sala_vl%TYPE := 2000;

    BEGIN UPDATE empr SET empr_sala_vl = empr_sala_vl + v_sal_increase WHERE EMPR_SERV_DS = 'ANALISTA';

    END;

    1.1.10. Excluso de Dados Exemplo 8: Deletar linhas que pertenam ao departamento 10 da tabela EMPR.

    DECLARE v_deptno empr.dept_nume_nr%TYPE := 10;

    BEGIN DELETE FROM empr WHERE dept_nume_nr = v_deptno;

    END;

    1.1.11. Controle de Transaes O controle da lgica das transaes realizado com as instrues COMMIT e ROLLBACK, tor-nando permanentes as alteraes em alguns grupos de bancos de dados e descartando outros. Assim como ocorre com o Oracle Server, as transaes DML so iniciadas no primeiro comando seguindo uma instruo COMMIT ou ROLLBACK e so finalizadas na prxima instruo COMMIT ou ROLLBACK correta. Essas aes podem ocorrer em um bloco PL/SQL ou como resultado dos eventos no ambiente do host (por exemplo, o encerramento de uma sesso SQL*Plus automati-camente compromete a transao pendente). 1.2. Estruturas de Controle As estruturas de controle permitem estabelecer o fluxo lgico de instrues que sero executadas. Para isso podem ser utilizadas as estruturas de controle para repetio de blocos do programa (loop) e as estruturas de controle para avaliao de condies e seleo (if).

    1.2.1. Estruturas de seleo As estruturas de seleo possibilitam que o fluxo de processamento das instrues PL/SQL seja direcionado de acordo com a condio especificada. Existem trs maneiras para se utilizar a ins-truo If: IF (condio) THEN Conjunto de instrues ; END IF;

    Neste caso, se o teste de avaliao da condio retornar verdadeiro o conjunto de instrues ser realizado, caso contrrio o bloco de seleo encerrado.

    IF(condio) THEN Conjunto de instrues 1; ELSE Conjunto de instrues 2; END IF;

    Neste caso, se o teste de avaliao da condio retornar verdadeiro o conjunto de instrues 1 ser realizado, caso contrrio o ser realizado o conjunto de instrues 2.

  • IF (condio1 ) THEN Conjunto de instrues 1; ELSIF (condio 2) Conjunto de instrues 2 ; ... ELSE Conjunto de instrues n; END IF;

    Neste caso, se o teste de avaliao da condio retornar verdadeiro, o conjunto de instrues 1 ser realizado, seno, ser realizado o teste de avaliao da condio 2. Se o resultado for verdadeiro ser realizado o conjunto de instrues 2, seno, ser realizado o teste avaliao da condio 3, e assim por diante. Caso nenhuma das condies testadas resultar verdadeiro ser realizado o conjunto de instrues previsto aps o ELSE.

    onde, condio uma expresso ou varivel Booleana (TRUE, FALSE ou NULL) (Ela est asso-

    ciada a uma seqncia de instrues, que ser executada somente se a expres-so produzir TRUE.)

    THEN uma clusula que associa a expresso Booleana que a precede com a seqn-cia de instrues posterior

    instrues pode ser uma ou mais instrues SQL ou PL/SQL. (Elas podem incluir mais ins-trues IF contendo diversos IFs, ELSEs e ELSIFs aninhados.)

    ELSIF uma palavra-chave que introduz uma expresso Booleana. (Se a primeira con-dio produzir FALSE ou NULL, a palavra-chave ELSIF introduzir condies adi-cionais.)

    ELSE uma palavra-chave que se for atingida pelo controle, executar a seqncia de instrues que segue a palavra-chave

    Exemplo 9: Definir o ID do gerente como 22 se o nome do funcionrio for OSBORNE

    ... IF v_ename = 'OSBORNE' THEN

    vEND IF;

    _mgr := 22;

    ... Exemplo 10: Definir o cargo como Salesman, o nmero do departamento como 35 e a comissao com o valor de 20% do salrio atual se o nome for MILLER.

    ... IF v_ename = MILLER THEN

    v_job := SALESMAN; v_deptno := 35; v_valor_com := sal * 0,20;

    END IF; ...

    Exemplo 11: Definir o cargo para Manager se o nome do funcionrio for King. Se o nome do fun-cionrio for diferente de King, defina o cargo para Clerk.

    ... IF v_ename = KING THEN

    v_job := MANAGER; ELSE

    v_job := CLERK; END IF; ...

    Exemplo 12: Dado um valor qualquer, representado pela varivel v_valor, calcule um percentual deste valor, de acordo com as condies estabelecidas, e armazene em v_perc_valor.

  • Se o valor for maior do que 100, 100% Se o valor for maior do que 50 e menor ou igual a 100, 50% Para os demais valores 10%

    ... IF v_valor > 100 THEN

    v_perc_valor := 2 * v_start; ELSIF v_valor >= 50 THEN

    v_perc_valor := .5 * v_start; ELSE

    v_perc_valor := .1 * v_start; END IF; ...

    ATENO: permitida qualquer quantidade de clusulas ELSIF, mas pode haver no mximo uma clusula ELSE. 1.2.2. Estruturas de repetio (Loop) Em determinadas situaes temos que repetir o programa ou parte dele inmeras vezes. Reiniciar o programa para cada repetio no uma soluo muito prtica, e algumas vezes invivel. Uma soluo comum a utilizao de estruturas de repetio. Segundo Puga i o conceito de repetio (ou looping) utilizado quando se deseja repetir certo tre-cho de instrues por um nmero de vezes. O nmero de repeties pode ser conhecido anterior-mente ou no, mas necessariamente precisa ser finito. Nem todas as estruturas de repetio possuem recursos para fazer a contagem do nmero de ve-zes que o lao dever ser repetido, por isso, deve-se utilizar uma varivel de apoio sempre do tipo inteiro. O PL/SQL oferece diversos recursos para estruturar laos de repetio:

    Loop bsico para fornecer aes repetitivas sem condies gerais Loops FOR para fornecer controle iterativo para aes com base em uma contagem Loops WHILE para fornecer controle iterativo para aes com base em uma condio

    ATENO: Instruo EXIT para termina o lao de repetio

    1.2.2.1 Loop Bsico Um loop bsico permite a execuo de sua instruo pelo menos uma vez, entretanto, se a condi-o exit for colocada no incio do loop, antes de qualquer outra instruo executvel, e ela for ver-dadeira, ocorrer a sada do loop e as instrues jamais sero executadas. Sem a instruo EXIT, o loop seria infinito! Sintaxe: LOOP delimitador de incio do lao conjunto de instrues; instrues a serem executadas em cada iterao EXIT [WHEN condio]; condio para sada do lao END LOOP; delimitador de fim do lao

    Pode-se emitir EXIT como uma ao dentro de uma instruo IF ou como uma instruo indepen-dente dentro do loop. Quando a instruo EXIT encontrada, a condio na clusula WHEN a-valiada, se a condio produzir TRUE, o loop finalizar e o controle passar para a prxima instru-o aps o loop. Um loop bsico pode conter vrias instrues EXIT..

  • Exemplo 13: Inserir os 10 primeiros novos itens de linha para o nmero do pedido 601.

    DECLARE v_ordid item.ordid%TYPE := 601; v

    BEGIN _counter NUMBER(2) := 1;

    LOOP INSERT INTO item (ordid, itemid) VALUES (v_ordid, v_counter); v_counter := v_counter + 1;

    EXIT WHEN v_counter > 10; END LOOP;

    END; 1.2.2.2 Loop FOR Os loops FOR, realizam as iteraes de acordo com a instruo de controle que precede a pala-vra-chave LOOP. Sintaxe: FOR contador in [REVERSE] limite_inferior..limite_superior LOOP conjunto de instrues; . . . END LOOP; onde, Contador um inteiro declarado implicitamente cujo valor aumenta ou diminui automati-

    camente (diminuir se a palavra-chave REVERSE for usada) em 1 a cada ite-rao do loop at o limite superior ou inferior a ser alcanado

    REVERSE faz o contador decrescer a cada iterao a partir do limite superior at o imite inferior. (Note que o limite inferior ainda referenciado primeiro.)

    limite_inferior especifica o limite inferior da faixa de valores do contador limite_superior especifica o limite superior da faixa de valores do contador ATENO: A seqncia de instrues executada sempre que o contador incrementado, con-forme determinado pelos dois limites. Os limites superiores e inferiores da faixa do loop podem ser literais, variveis ou expresses, mas devem ser avaliados para inteiros. Se o limite inferior da fai-xa do loop for avaliado para um inteiro maior do que o limite superior, a seqncia de instrues no ser executada. Exemplo 14: Inserir os 10 primeiros novos itens de linha para o nmero do pedido 601.

    DECLARE v_ordid item.ordid%TYPE := 601;

    BEGIN FOR i IN 1..10 LOOP

    INSERT INTO item(ordid, itemid) VALUES(v_ordid, i);

    END LOOP; END;

    1.2.2.3 Loop WHILE Pode-se usar o loop WHILE para repetir uma seqncia de instrues at que a condio para controle no seja mais verdadeira, a condio avaliada ao incio de cada iterao, sendo assim, se a condio for falsa no incio do loop, nenhuma iterao futura ser executada.

  • Sintaxe: WHILE condio LOOP conjunto de instrues; . . . END LOOP; Onde, condio uma expresso ou varivel Booleana (TRUE, FALSE, ou NULL) instruo pode ser uma ou mais instrues SQL ou PL/SQL ATENO:

    Se as variveis envolvidas nas condies no se alterarem no curso do corpo do loop, a condio permanecer TRUE e o loop no terminar.

    Se a condio produzir NULL, o loop ser ignorado e o controle passar para a prxima

    instruo. Exemplo 15: Solicitar o nmero de iteraes do lao e exibir o valor da varivel de controle a cada iterao.

    ACCEPT p_no_voltas PROMPT 'Digitar o nmero de voltas do lao: ' DECLARE

    vBEGIN

    _count NUMBER(2) := 1;

    WHILE v_count 10; LOOP

    ...

  • EXIT Outer_loop WHEN total_done = 'YES'; -- Abandona ambos os Loops EXIT WHEN inner_done = 'YES'; -- Abandona somente o Loop interno

    ... END LOOP loop_interno;

    ... END LOOP loop_externo;

    END; . . .

    1.3. Cursores Para processar uma instruo de SQL o Oracle atribui uma rea de memria denominada rea de contexto. A rea de contexto contm o nmero de linhas processadas, um apontador e, para con-sultas, o conjunto ativo. O conjunto ativo o conjunto de linhas recuperadas uma consulta, por e-xemplo:

    A consulta select * from EMPR ter como conjunto ativo todas as linhas e colunas da tabela

    EMPR; Na consulta select EMPR_NOME_DS, EMPR_SERV_DS from EMPR where

    DEPT_NUME_NR = 20, o conjunto ativo ser composto pelas linhas e colunas que atendem condio.

    O cursor o apontador da rea de contexto. Existem dois tipos de cursores os cursores: Implcitos: no declarado e realizado implicitamente quando as instrues DML e PL/SQL

    select ..into so realizadas. Processam apenas uma linha. Se uma consulta retornar mais do que uma linha um erro ser gerado.

    Explcitos: precisam ser declarados explicitamente na rea declarativa do bloco PL/SQL. Po-de processar vrias linhas; por meio de um cursor explcito possvel, em um bloco PL/SQL, controlar a rea de contexto e os processamentos que nela ocorrem

    ATENO: Todos os exemplos de blocos PL/SQL, apresentados at este ponto e que continham instrues DML so exemplos de cursores implcitos. Os atributos de cursores podem ser utilizados em cursores implcitos ou explcitos. Estes atributos permitem a realizao de testes nos resultados das instrues SQL, so eles: %FOUND: retorna verdadeiro caso alguma linha (tupla) tenha sido afetada %NOTFOUND: retorna verdadeiro caso no tenha encontrado nenhuma tupla. Seu valor fal-

    so at a ltima tupla. %ISOPEN: indica se o cursor est aberto ou no. %ROWCOUNT: retorna o nmero de tuplas do cursor. Exemplo 17: Deletar linhas que especificaram um nmero de ordem de compra a partir da tabela ITEM. Exibir o nmero de linhas deletadas.

    VARIABLE linhas_deletadas VARCHAR2(30) DECLARE

    vBEGIN

    _deptno NUMBER := 10;

    DELETE FROM EMPR WHERE DEPT_NUME_NR = v_deptno; :linhas_deletadas := (SQL%ROWCOUNT || ' linhas deletadas.');

    END; /

  • PRINT linhas_deletadas O exemplo 17 um cursor implcito, o atributo SQL%ROWCOUNT est sendo utilizado para pos-sibilitar a exibio do nmero de linhas deletadas.

    1.3.1. Cursores Explcitos O Oracle Server usa reas de trabalho chamadas reas SQL particulares para executar instrues SQL e para armazenar informaes de processamento. Pode-se usar cursores do PL/SQL para nomear uma rea SQL particular e acessar suas informaes armazenadas. Os cursores explcitos podem ser utilizados para processar individualmente cada linha retornada por uma instruo SE-LECT de vrias linhas. O cursor orienta todas as fases do processamento. Conjunto Ativo Linha atual

    7369 SMITH CLERK

    7566 JONES MANAGER

    7788 SCOTT ANALYST

    7876 ADAMS CLERK

    7902 FORD ANALYST

    cursor

    O conjunto de linhas retornado por uma consulta de vrias linhas chamado conjunto ativo. Seu tamanho correspondente ao nmero de linhas que atende aos critrios da pesquisa. A figura an-terior mostra como um cursor explcito "aponta" para a linha atual do conjunto ativo. Isso permite que o programa processe as linhas uma de cada vez. Um programa PL/SQL abre um cursor, processa linhas retornadas por uma consulta e, em segui-da, fecha o cursor. O cursor marca a posio atual no conjunto ativo. A seqncia para execuo do controle dos cursores consiste em:

    Declarao

    Abertura

    Recuperao das

    Linhas

    Verificao do

    trmino

    Fechamento

    1. Declare o cursor nomeando-o e definindo a estrutura da consulta a ser executada dentro

    dele. 2. Abra o cursor. A instruo OPEN executa a consulta e vincula as variveis que estiverem

    referenciadas. As linhas identificadas pela consulta so chamadas conjunto ativo e esto agora disponveis para extrao.

    3. Extraia dados do cursor. No diagrama de fluxo mostrado no slide, aps cada extrao voc testa o cursor para qualquer linha existente. Se no existirem mais linhas para serem pro-cessadas, voc precisar fechar o cursor.

    4. Feche o cursor. A instruo CLOSE libera o conjunto ativo de linhas. Agora possvel rea-brir o cursor e estabelecer um novo conjunto ativo.

    1.3.1.1 Declarao de cursores explcitos Os cursores explcitos devem ser declarados no bloco PL/SQL e a manipulao do seu conjunto ativo deve ser realizada na rea de processamento do bloco. Sintaxe:

    CURSOR nome_cursor IS consulta;

    Onde,

    CURSOR a instruo utilizada para declarar um cursor explcito.

  • nome_cursor um identificador para o cursor consulta uma instruo SELECT

    ATENO: No se deve incluir a clusula INTO na declarao de cursor porque ela aparecer posteri-

    ormente na instruo FETCH. Pode-se fazer referncia a variveis dentro da consulta, mas elas devem ser declaradas

    antes da instruo CURSOR. Exemplo 18: Declarar cursores para recuperar o cdigo e o nome de todos os funcionrios e para recuperar todas as colunas da tabela dept quando o cdigo do departamento for igual a 10.

    DECLARE CURSOR EMPR_cursor IS SELECT EMPRno, EMPR_NOME_DS FROM EMPR; CURSOR dept_cursor IS SELECT * FROM dept WHERE deptno = 10; BEGIN ...

    1.3.1.2 Abertura do Cursor A instruo OPEN abre o cursor para executar a consulta e identificar o conjunto ativo, que consis-te em todas as linhas que atendem aos critrios de pesquisa da consulta. O cursor aponta agora para a primeira linha do conjunto ativo. Sintaxe:

    OPEN nome_cursor; OPEN uma instruo executvel que realiza as seguintes operaes:

    1) Aloca memria dinamicamente para uma rea de contexto que finalmente conter in-formaes cruciais de processamento.

    2) Analisa a instruo SELECT. 3) Vincula as variveis de entrada isto , define o valor das variveis de entrada obten-

    do seus endereos de memria. 4) Identifica o conjunto ativo isto , o conjunto de linhas que satisfaz os critrios de

    pesquisa. As linhas no conjunto ativo no so recuperadas para variveis quando a ins-truo OPEN executada. Em vez disso, a instruo FETCH recupera as linhas.

    5) Posiciona o indicador imediatamente antes da primeira linha no conjunto ativo.

    ATENO: Se a consulta no retornar qualquer linha quando o cursor for aberto, o PL/SQL no criar uma exceo , pode-se testar o status do cursor aps a extrao. 1.3.1.3 Recuperao das linhas do Cursor A instruo FETCH recupera as linhas no conjunto ativo uma de cada vez. Aps cada extrao, o cursor avana para a prxima linha no conjunto ativo. Sintaxe: FETCH cursor_name INTO [varivel1, varivel2, ...|record_name];

  • onde, cursor_name o nome do cursor declarado anteriormente varivel uma varivel de sada para armazenar os resultados, o nmero de

    variveis deve ser compatvel com o nmero de colunas da consulta. record_name o nome do registro em que os dados recuperados so armazenados (A

    varivel de registro pode ser declarada usando o atributo %ROWTY-PE.)

    A instruo FETCH realiza as seguintes operaes:

    1) Avana o indicador para a prxima linha no conjunto ativo.

    2) L os dados da linha atual para as variveis PL/SQL de sada. Deve-se incluir o mesmo nmero de variveis na clusula INTO da instruo FETCH do que as co-lunas na instruo SELECT, as variveis devem ser do mesmo tipo de dado da coluna correspon-dente. Como alternativa, pode ser definido um registro para o cursor e faa referncia do registro na clusula FETCH INTO. Verificar se o cursor possui linhas. Se uma extrao no obtiver valores, no existem linhas rema-nescentes para serem processadas no conjunto ativo e nenhum erro ser registrado.

    1.3.1.4 Fechamento de Cursor A instruo CLOSE desativa o cursor e o conjunto ativo se torna indefinido. O cursor deve ser fe-chado aps completar o processamento da instruo SELECT. Essa etapa permite que o cursor seja reaberto, se necessrio. Assim, pode-se estabelecer um conjunto ativo diversas vezes; A -rea de contexto liberada. Sintaxe:

    CLOSE nome_cursor; Embora seja possvel terminar o bloco PL/SQL sem fechar cursores, deve-se criar o hbito de fe-char qualquer cursor declarado explicitamente para liberar recursos. Existe um limite mximo para o nmero de cursores abertos por usurio, que determinado pelo parmetro OPEN_CURSORS no campo de parmetros do banco de dados. OPEN_CURSORS = 50 por default. Exemplo 19: Criar um bloco PL/SQL no qual seja calculado o salrio anual de cada funcionrio e armazene na tabela sal_tot o nome do funcionrio e o seu salrio anual. 1 ACCEPT p_cargo_func PROMPT 'Digite o CARGO do funcionrio ' 2 VARIABLE g_n_ocorrencias NUMBER; 3 DECLARE 4 v_cargo_func EMPR_SERV_DS%TYPE := '&p_cargo_func'; 5 v_nome_func EMPR_NOME_DS%TYPE; 6 v_sal_mes EMPR_SALA_VL%TYPE; 7 v_sal_ano number(9,2); 8 CURSOR sal_func_cursor IS 9 SELECT EMPR_NOME_DS, EMPR_SALA_VL, EMPR_SALA_VL * 12 10 FROM EMPR 11 WHERE EMPR_SERV_DS = v_cargo_func; 12 BEGIN 13 OPEN sal_func_cursor; 14 LOOP 15 FETCH sal_func_cursor INTO v_nome_func, v_sal_mes, v_sal_ano; 16 EXIT WHEN sal_func_cursor%NOTFOUND; 17 INSERT INTO sal_tot VALUES(v_nome_func, v_sal_ano); 18 END LOOP;

  • 19 :g_n_ocorrencias := sal_func_cursor%ROWCOUNT; 20 CLOSE sal_func_cursor; 21 END; 22 / 23 PRINT g_n_ocorrencias Sobre o exemplo: As linhas do exemplo 19 foram enumeradas para facilitar a explicao sobre o cdigo. Na linha 8 est sendo iniciada a declarao do cursor sal_func_cursor, observe que na linha 11, na condio para recuperao das linhas do cursor, utilizada a varivel v_cargo_func que foi decla-rada anteriormente na linha 4. Na linha 13 o cursor aberto. Na linha 14 iniciado o lao de repetio que ser encerrado quando no existirem mais linhas no conjunto ativo para serem percorridas (linha 16) Na linha 15 a instruo fetch recupera a linha corrente do conjunto ativo e armazena os dados das colunas nas variveis v_nome_func, v_sal_mes, v_sal_ano Na linha 17 os valores recuperados so inseridos na tabela sal_tot. Na linha 20 o cursor fechado.

    1.3.2. Cursores de Atualizao Os registros retornados pela consulta que est associada a um cursor podem ser lidos, alterados ou excludos. Os cursores que permitem este tipo de operao so chamados cursores de atuali-zao e devem ser declarados da seguinte maneira: cursor nome_cursor is select ... from ... (consulta) for update [of nome_coluna] [nowait]; Veja o exemplo de um cursor para atualizao e a seguir as explicaes do cdigo e das clusulas da sintaxe: 1 Declare 2 cursor cursor_ex_atual 3 Is 4 select EMPR_NOME_DS, EMPR_SERV_DS, sal 5 from EMPR 6 for update of sal nowait; 7 Begin 8 for reg_ex_atual in cursor_ex_atual loop 9 if reg_ex_atual.job = CLERK then 10 update EMPR set sal = sal * 1.10 11 where current of cursor_ex_atual; 12 elseif reg_ex_atual.job = PRESIDENT then 13 update EMPR set sal = sal + sal 14 where current of cursor_ex_atual; 15 Else 16 delete from EMPR 17 where current of cursor_ex_atual; 18 end loop;

    Sobre o cdigo:

    A clusula for update, utilizada na linha 6, deve ser a ltima instruo da declarao de um cursor e indica que os registros retornados pelo cursor podero ser atualizados (alterados ou excludos)

  • of sal, linha 6, indica a coluna ou lista de colunas de referncia para consulta, neste caso sal a coluna que ser atualizada. Est expresso opcional.

    A clusula nowait, linha 6, deve ser utilizada para gerar uma exceo tratvel caso a tabela esteja bloqueada por outro usurio, isto , ser emitida uma mensagem informando que a tabela a ser utilizada est bloqueada por outro usurio. Est clusula opcional, no entan-to, se for omitida o cursor de atualizao ficar por tempo indeterminado esperando o des-bloqueio da tabela para que prossiga com a consulta.

    A varivel reg_ex_atual, declarada implicitamente como cursor_ex_atual%rowtype, (na li-nha 8), isto , est varivel do tipo registro e possui os mesmos campos utilizados na consulta associada ao cursor. Isso ocorre toda vez que a instruo for utilizada para con-trolar a leitura dos registros retornados pela consulta em questo.

    Para referenciar um campo deve-se colocar o nome da varivel . (ponto) e o nome do cam-po, por exemplo: reg_ex_atual.job est sendo referenciado o campo EMPR_SERV_DS da tabela EMPR.

    A instruo where current of nome_cursor, linhas 11, 14 e 17, indica que a operao de atualizao ou excluso ser realizada no registro corrente, isto , no registro que est sendo apontado pelo cursor naquele momento.

    1.3.3. Variveis de Cursores Os cursores vistos at ento, so estticos, isto , o cursor associado a uma instruo SQL que em tempo de compilao retorna os registros associados quela consulta. As variveis de cursor podem ser utilizadas para receber valores em tempo de execuo possibilitando que diferentes re-sultados sejam obtidos a partir de um nico cursor. As variveis de cursor so do tipo referncia e devem ser declarados da seguinte maneira: TYPE nome_tipo IS REF CURSOR RETURN tipo_retorno; onde,

    nome_tipo o nome do tipo de referncia o tipo de retorno tem que ser do tipo registro Variveis do tipo referncia (REF) so como apontadores, isto , apontam para diferentes reas de memria ao longo da utilizao do programa, so diferentes das variveis comuns que so utili-zadas para identificar uma rea de memria. Variveis do tipo registro podem ser declaradas utilizando %ROWTYPE Exemplos de declaraes de variveis de cursor: Exemplo 1

    TYPE t_registro IS RECORD ( nome EMP.EMPR_NOME_DS%type, cargo EMPR_SERV_DS%type); v_registro t_registro; TYPE t_referencia IS REF CURSOR RETURN t_registro;

    sobre o exemplo:

    est sendo declarada o tipo t_registro, do tipo registro. Este registro ser composto pelos campos nome e cargo que possuem respectivamente o formato do campo EM-PR_NOME_DS da tabela EMPR e EMPR_SERV_DS da mesma tabela.

    est sendo declarada a varivel v_registro que ser do tipo t_registro, tipo construido na declarao anterior

    est sendo declarado o tipo referncia t_referencia para o cursor, que ter como retorno o valor de t_registro.

    Exemplo 2- usando %ROWTYPE:

    TYPE t_AlunoRef IS REF CURSOR RETURN aluno%ROWTYPE;

  • Para abrir uma varivel de cursor para consulta

    OPEN varivel_cursor FOR consulta_pretendida Exemplo:

    DECLARE TYPE t_AlunoRef IS REF CURSOR RETURN aluno%ROWTYPE; v_aluno t_alunoRef; ... BEGIN ...

    OPEN v_aluno FOR SELECT nome, curso from ALUNO; ...

    ATENO: O retorno do cursor deve ser compatvel com o retorno da consulta, caso contrrio o-correr um erro. 1.4. Tratamento de Excees Uma exceo uma ocorrncia no esperada, ou diferente daquela programada para ser execu-tada. Em outras palavras uma exceo um erro! Por exemplo: O usurio digita um caractere para uma varivel do tipo numrico, neste exemplo temos uma en-trada de dados diferente da esperada; um cursor declarado com um retorno que espera um conjunto de campos diferentes daqueles que so solicitados pela consulta; Os erros podem ocorrer durante a compilao ou durante a execuo do programa. Os erros de compilao esto associados a sintaxe das instrues: nome dos comandos, declarao das vari-veis, organizao dos comandos, entre outros. Neste tipo de erro o compilador da linguagem in-forma ao programador durante a tentativa de executar uma instruo a ocorrncia do erro: Exemplo: SQL> selet * from EMPR; SP2-0734: incio de comando desconhecido "selet * fr..." - restante da linha ignorado. Os erros de execuo (runtime) esto associados utilizao do programa, neste caso quando as excees no so previstas e tratadas, o erro gerado por elas interrompe o processamento e uma mensagem devolvida para a aplicao. Exemplo: Ao executar o programa zero.sql, ser gerado um erro pela tentativa de dividir um va-lor por zero

    declare x number := 0; y number := 5; resultado number; begin resultado := y / x; ... end;

    Compilando o programa:

    SQL> @zero.sql declare *

  • ERRO na linha 1: ORA-01476: o divisor igual a zero ORA-06512: em line 6

    Para realizao da operao aritmtica de diviso, o divisor dever ser diferente de 0. No existe erro de sintaxe, mas, o valor esperado para divisor no est adequado, fazendo com que o pro-grama no funcione, ento, temos uma exceo! Para resolver este problema algumas linguagens de programao oferecem recursos para trata-mento de excees. O tratamento de uma exceo consiste em identificar um erro em tempo de execuo e trat-lo de maneira que o usurio seja informado sobre o que est acontecendo e o programa no seja interrompido bruscamente. O Oracle possui alguma excees pr-definidas, mas o desenvolvedor tambm pode definir exce-es personalizadas. O bloco PL/SQL com tratamento de excees tem a seguinte estrutura:

    DECLARE nome_exceo exception; /* declarao da exceo BEGIN RAISE exceo; /* abertura da exceo EXCEPTION /* rea de tratamento das excees WHEN nome_exceo THEN instrues para tratamento da exceo; WHEN OTHERS THEN instrues para tratamento da exceo; END;

    1.4.1. Excees pr-definidas nomeadas Para alguns erros comuns, existem pr-definies de excees, no havendo, neste caso, a ne-cessidade de serem declaradas para serem utilizadas. Exemplo 1: 1 ACCEPT p_nome PROMPT Digite o nome do funcionrio ... 2 DECLARE 3 v_nome EMP.EMPR_NOME_DS%type := &p_nome; 4 BEGIN 5 SELECT EMPR_NOME_DS, sal 6 FROM EMPR 7 WHERE EMPR_SERV_DS = 'CLERK' and EMPR_NOME_DS = v_nome; 8 EXCEPTION 9 when NO_DATA_FOUND then 10 DBMS_OUTPUT.PUT_LINE('Nenhum registro foi encontrado'); 11 when TOO_MANY_ROWS then 12 DBMS_OUTPUT.PUT_LINE('Muitos funcionrios possuem este cargo'); 13 when OTHERS then 14 DBMS_OUTPUT.PUT_LINE('ERRO DESCONHECIDO ' ); 15 END;

    Neste exemplo, est sendo realizada uma consulta (linha 5), como esta consulta no est associada a um cursor explcito, dever retornar apenas um registro, caso contrrio uma exceo ser gerada, isto ocorre pois no est sendo reservada uma rea para armazenamento destas in-formaes e nem tampouco os dados retornados esto associados variveis ou existe uma es-trutura de repetio. Se nenhuma linha for retornada tambm ser gerada uma exceo. Estas du-as excees so pr definidas pelo Oracle como NO_DATA_FOUND (linha 9) e TO-O_MANY_ROWS (linha 11).

  • A seo de tratamento de exceo captura somente as excees especificadas; quaisquer outras excees no sero capturadas exceto se for utilizado o handler de exceo OTHERS. Es-se handler captura qualquer exceo que ainda no esteja tratada. Por essa razo, OTHERS o ltimo handler de exceo definido.

    No exemplo, na clusula OTHERS (linha 13), se ocorrer qualquer outra exceo, diferente de NO_DATA_FOUND e TOO_MANY_ROWS ser exibida a mensagem 'ERRO DESCONHECI-DO '. ATENO: Podem ser definidos vrios handlers de exceo para o bloco, cada um deles com o seu prprio conjunto de aes. Quando ocorre uma exceo, o cdigo PL/SQL processa somente um handler antes de sair do bloco. As excees no podem aparecer em instrues de atribuio ou instrues SQL. Funes para Captura de Erro Quando ocorre uma exceo, pode-se identificar o cdigo ou a mensagem de erro associado u-sando duas funes SQLCODE e SQLERRM. Com base nos valores do cdigo ou mensagem, vo-c pode decidir qual ao subseqente tomar com base no erro. SQLERRM Funo numrica que devolve o cdigo do erro; SQLCODE Funo caractere que devolve o texto da mensagem do erro. Quando uma exceo capturada no handler de exceo WHEN OTHERS, pode-se usar um con-junto de funes genricas para identificar esses erros. No exemplo a seguir os valores de SQLCODE e SQLERRM esto sendo atribudos a variveis e, em seguida, essas variveis sendo usadas em uma instruo SQL. Exemplo: 1 DECLARE 2 v_error_code NUMBER; 3 v_error_message VARCHAR2(255); 4 BEGIN 5 ... 6 EXCEPTION 7 ... 8 WHEN OTHERS THEN 9 ROLLBACK; 10 v_error_code := SQLCODE ; 11 v_error_message := SQLERRM ; 12 INSERT INTO errors 13 VALUES(v_error_code, v_error_message); 14 END; ATENO: Trunque o valor de SQLERRM para um tamanho conhecido antes de tentar grav-lo para uma varivel. 1.4.2. Excees nomeadas pelo desenvolvedor e associadas a cdigos de erro : Devem ser declaradas explicitamente na seo de declaraes e abertas na rea de processa-mento quanto houver a possibilidade de erro: Exemplo:

    set verify on accept p_deptno prompt ' insira o numero do departamento ' accept p_local prompt ' insira a localizaao do depto ' DECLARE e_depto_invalido EXCEPTION;

  • v_deptno dept.deptno%type := &p_deptno; BEGIN Update dept set loc = '&p_local'

    0 where deptno = v_deptno; 1 IF sql%notfound then 2 Raise e_depto_invalido; 3 end if; 4 commit; 5 EXCEPTION 6 when e_depto_invalido then 7 dbms_output.put_line('departamento ' || to_char(v_deptno) || ' nao

    cadastrado'); 8 END;

    onde:

    e_depto_invalido EXCEPTION; - (linha 5) est sendo declarada a exceo e_depto_invalido

    caso a instruo para atualizao da tabela no encontre registros para efetuar a transa-

    o, bloco de seleo IF (linha 11) abre a exceo e_depto invlido ento o fluxo do pro-grama desviado para a rea de tratamento de excees.

    Algumas excees declaradas pelo usurio podem ser associadas a erros Oracle pr-definidos, mas no nomeados. Podemos associar estas excees a um nome da seguinte maneira:

    PRAGMA EXCEPTION_INIT (nome_exceo, cdigo_Oracle_erro); onde,

    nome_exceo deve ser declarada na rea declarativa codigo_Oracle_erro deve-se associar a exceo declarada ao nmero de erro padro

    Na rea de excees deve-se fazer referncia exceo declarada dentro da rotina de tratamento de exceo correspondente. O PRAGMA EXCEPTION_INIT uma diretiva de compilao que informa o compilador para as-sociar um nome de exceo a um nmero de erro do Oracle. Isso permite que possa ser consulta-da qualquer exceo interna por nome e criado um handler especfico para ela. ATENO: PRAGMA (tambm chamado pseudo-instrues) uma palavra-chave que signi-fica que a instruo uma diretiva de compilador, que no processada ao executar o blo-co PL/SQL. Ao invs disso, orienta o compilador do PL/SQL para interpretar todas as ocor-rncias do nome da exceo dentro do bloco como o nmero de erro do Oracle Server as-sociado. Exemplo: Capturar por nmero de erro do Oracle Server 2292, uma violao de restrio de in-tegridade. Se um determinado usurio tentar remover um departamento, para o qual existam fun-cionrios, imprima uma mensagem informando que esse departamento no pode ser removido. 1 DECLARE 2 e_emps_remaining EXCEPTION; 3 PRAGMA EXCEPTION_INIT ( e_emps_remaining, -2292); 4 v_deptno dept.deptno%TYPE := &p_deptno; 5 BEGIN 6 DELETE FROM dept 7 WHERE deptno = v_deptno; 8 COMMIT; 9 EXCEPTION

  • 10 WHEN e_emps_remaining THEN 11 DBMS_OUTPUT.PUT_LINE (No possvel remover o departamento ||

    TO_CHAR(v_deptno) || '. Existem funcionrios. '); 12 END; Na linha 2 est sendo declarada a exceo e_emps_remaining. Na linha 3 a exceo declarada est sendo associada ao erro oracle 2292. Excees declaradas e definidas pelo desenvolvedor O PL/SQL permite que voc defina suas prprias excees. As excees PL/SQL definidas pelo usurio devem ser: Declaradas na seo de declarao de um bloco PL/SQL Criadas explicitamente com instrues RAISE Exemplo: Esse bloco atualiza a descrio de um produto. O usurio fornece o nmero do produto e a nova descrio. Se o usurio incluir um nmero de produto inexistente, nenhuma linha ser a-tualizada na tabela PRODUCT. Crie uma exceo e imprima uma mensagem para o usurio aler-tando-os de que foi includo um nmero de produto invlido. 1 DECLARE 2 e_invalid_product EXCEPTION; 3 BEGIN 4 UPDATE product 5 SET descrip = '&product_description' 6 WHERE prodid = &product_number; 7 IF SQL%NOTFOUND THEN 8 RAISE e_invalid_product; 9 END IF; 10 COMMIT; 11 EXCEPTION 12 WHEN e_invalid_product THEN 13 DBMS_OUTPUT.PUT_LINE('Invalid product number.'); 14 END; Na linha 2 a exceo est sendo declarada; Na linha 8 est sendo criada explicitamente; e Na linha 12 est sendo tratada. Procedimento RAISE_APPLICATION_ERROR O procedimento RAISE_APPLICATION_ERROR utilizado para comunicar uma exceo predefi-nida interativamente retornando um cdigo ou uma mensagem de erro no padronizada. Com RAISE_APPLICATION_ERROR possvel relatar erros para a aplicao e evitar o retorno de ex-cees no tratveis. Sintaxe: RAISE_APPLICATION_ERROR (numero_erro, mensagem[, {TRUE | FALSE}]); Onde: nmero_erro um nmero especificado pelo usurio para a exceo entre 20000 e 20999. mensagem a mensagem especificada pelo usurio para a exceo. Trata-se de uma string de caracteres com at 2.048 bytes. TRUE | FALSE um parmetro Booleano opcional (Se TRUE, o erro ser colocado na pilha de erros anteriores. Se FALSE, o default, o erro substituir todos os erros anteriores.) O procedimento RAISE_APPLICATION_ERROR pode ser usado em dois locais diferentes: Na seo de exceo

  • Na seo executvel Exemplo 1 : Utilizando na seo de excees

    ... EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR (-20201, 'Manager is not a valid EMPRloyee.'); END;

    Exemplo 2 : Utilizando na seo de executvel

    ... BEGIN ... DELETE FROM EMPR WHERE mgr = v_mgr; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR(-20202,'This is not a valid manager'); END IF; ...

    Propagando uma Exceo para um Sub-bloco Ao invs de se capturar uma exceo dentro do bloco PL/SQL, possvel propagar a exceo pa-ra permitir que ela seja tratada pelo ambiente de chamada. Cada ambiente de chamada tem seu prprio modo de exibir e acessar erros. Exemplo: DECLARE . . . e_no_rows exception; e_integrity exception; PRAGMA EXCEPTION_INIT (e_integrity, -2292); BEGIN FOR c_record IN EMPR_cursor LOOP BEGIN SELECT ... UPDATE ... IF SQL%NOTFOUND THEN RAISE e_no_rows; END IF; EXCEPTION WHEN e_integrity THEN ... WHEN e_no_rows THEN ... END; END LOOP; EXCEPTION WHEN NO_DATA_FOUND THEN . . . WHEN TOO_MANY_ROWS THEN . . . END;

    Quando um sub-bloco trata uma exceo, ele termina normalmente e o controle retorna ao bloco delimitado imediatamente aps a instruo END do sub-bloco. Entretanto, se o cdigo PL/SQL criar uma exceo e o bloco atual no tiver um handler para essa exceo, a exceo propagar em blocos delimitados sucessivos at localizar um handler. Se ne-nhum desses blocos tratar a exceo, o resultado ser uma exceo no tratvel no ambiente de host (chamador).

  • Quando a exceo propaga para um bloco delimitado, as aes executveis restantes desse bloco so ignoradas. Uma vantagem desse comportamento que pode-se delimitar instrues que exigem seus pr-prios tratamentos de erro exclusivos em seu prprio bloco, enquanto deixa o tratamento de exce-o mais geral para o bloco delimitado. 1.5. Procedimentos

    Um procedimento um conjunto de instrues que realiza determinada tarefa. (Puga[2003]). A de-finio e o funcionamento dos procedimentos similar programao em outras linguagens e en-volve basicamente os passos de

    identificao do procedimento definio dos parmetros ou parmetro conjunto de instrues do procedimento submisso do cdigo ao SGBDR

    Ento,

    O cdigo fonte armazenado no dicionrio de dados1 O procedimento compilado

    o se a compilao for bem sucedida o P-code armazenado no dicionrio de dados e no pode ser consultado

    o se ocorrerem erros de compilao, estes sero armazenados no USER_ERRORS Sintaxe: CREATE [ OR REPLACE] nome_procedimento [parmetro [{in, out, in out}] tipo_parmetro, ... {IS ou AS}

    BEGIN corpo_do_procedimento

    END [nome_procedimento];

    onde:

    Create or replace instruo para criao ou substituio do procedi-mento

    nome_procedimento nome que ser dado ao procedimento parmetro [parmetro [{in, out, in out}]

    nome do parmetro que poder ser para entrada, sa-da ou entrada e sada

    tipo_parmetro tipo de dado que o parmetro poder aceitar, os pa-rmetros podem ser IN, OUT ou IN OUT

    IS ou AS tem a mesma funo e indicam o bloco que estar associado ao procedimento, substitui a palavra re-servada DECLARE.

    BEGIN corpo_do_procedimento END Respectivamente o incio do bloco, o conjunto de ins-trues do procedimento e o final do bloco.

    1 Pode-se consultar a USER_SOURCE

  • 1.5.1. Utilizando parmetros2 de entrada Os parmetros so por default do tipo IN, isto , so utilizados para entrada de valores que sero utilizados internamente pelo procedimento.

    A procedure reajuste recebe os parmetros v_cdigo e v_porcentagem cujos valores sero utilizados para alterao de um registro na tabela EMPR.

    CREATE OR REPLACE PROCEDURE reajuste (v_codigo_emp IN EMPR_NUME_NR%type, v_porcentagem IN number)

    IS BEGIN UPDATE EMPR SET sal = sal + (sal *( v_porcentagem / 100 ) ) where EMPRno = v_codigo_emp; COMMIT; END reajuste; /

    Os parmetros IN podem receber valores default: v_porcentagem IN number default 25. ATENO: Somente os parmetros IN podem ser atribudos de valores default, os parmetros OUT e IN OUT no podem.

    1.5.2. Utilizando parmetros de sada Os parmetros do tipo OUT so utilizados para sada de valores processados para o ambiente de chamada. A procedure consulta_emp recebe o parmetro de entrada p_id, que ser utilizado na condio da consulta para recuperar o registro de um dado funcionrio. O parmetro de sada p_salrio ser utilizado para devolver o valor, resultado de uma operao interna da procedure, para a rotina chamadora. (no item 1.1.5 ser exemplificada a utilizao das procedures)

    CREATE OR REPLACE PROCEDURE consulta_emp (p_id in EMPR_NUME_NR%type,

    p_nome out EMP.EMPR_NOME_DS%type, p_salario out EMPR.sal%type) BEGIN

    IS select EMPR_NOME_DS, sal into p_nome, p_salario from EMPR where EMPRno = p_id; END consulta_emp; /

    2 Parmetro um valor, constante ou varivel, que passado de uma rotina chamadora para uma rotina e-xecutora, onde a rotina chamadora um algoritmo que usa as funcionalidades da rotina executora, por e-xemplo: Parmetro formal variveis da rotina executora que recebem os valores da rotina cha-madora, isto , recebem os parmetros reais. ATENO: As variveis dos parmetros formais no devem ter tamanho ou preciso pr determinados. Parmetro real valores (constantes ou reais) que so passados da rotina chamadora para a rotina executo-ra.

  • 1.5.3. Utilizando parmetros de entrada e sada Os parmetros IN OUT so utilizados para entrada de valores, que podero ser processados, o parmetro poder ser alterado e o seu valor pode ser devolvido para o ambiente de chamada. A procedure formata_fone recebe o parmetro p_fone, que representa uma cadeia de caracteres. Este parmetro recebe de o resultado das operaes da procedure e devolte este valor a rotina chamadora. Sendo assim um parmetro de entrada quando passa para a procedure o valor que ser utilizado no processamento, um parmetro de sada quando recebe o resultado do processamento, por-tanto, tem o seu valor alterado, e devolve o resultado rotina chamadora.

    CREATE OR REPLACE PROCEDURE formata_fone (p_fone IN OUT varchar2) IS BEGIN P_fone := ( || substr(p_fone, 1, 3) || ) || substr(p_fone, 4, 3) || - || substr(p_fone, 7); END formata_fone; /

    As instrues para criao do procedimento podem ser digitadas diretamente no prompt do S-QL*Plus ou em um arquivo com extenso sql. Se o cdigo for escrito diretamente no prompt ao te-clar enter aps a barra ( / ) ser compilado e o procedimento ser criado. Uma mensagem informa-r se o procedimento foi criado com sucesso ou com erros.

  • 1.5.4. Visualizao de erros de compilao Quando as compilaes no so bem sucedidas a instruo show errors pode ser utilizada para visualizar os erros que ocorreram: Sintaxe:

    SQL> show errors resultado:

    Erros para PROCEDURE REAJUSTE: LINE/COL ERROR -------- ------------------------------------------- 8/2 PL/SQL: SQL Statement ignored 10/26 PL/SQL: ORA-00904: nome invlido de coluna

    1.5.5. Utilizao de procedimentos Os procedimentos podem ser chamados atravs do SQL*Plus, de outros procedimentos ou fun-es ou de outros aplicativos pr compilados. Exemplo 1: Para chamar procedimentos a partir do prompt do SQL*Plus: Este exemplo utiliza a procedure reajuste que opera com parmetros de entrada: SQL> execute reajuste(7934, 10) Procedimento PL/SQL concludo com sucesso. Exemplo 2: Para chamar o procedimento de um bloco PL/SQL annimo: Este exemplo utiliza a procedure reajuste (que opera com parmetros de entrada) e a procedure consulta_emp (que ope-ra com parmetros de sada):

    1. Editar as instrues em um arquivo com extenso sql

    SQL> edit usa_proc.sql

    ACCEPT p_cod PROMPT 'cdigo do funcionrio..... ' ACCEPT p_perc PROMPT 'percentual de aumento..... ' VARIABLE g_nome varchar2(25) VARIABLE g_sal number DECLARE

    v_nome EMP.EMPR_NOME_DS%type; v_sal EMPR.sal%type;

    BEGIN

    SELECT EMPR_NOME_DS, sal INTO v_nome, v_sal FROM EMPR WHERE EMPRno = &p_cod; reajuste(&p_cod, &p_perc); consulta_emp(&p_cod, :g_nome, :g_sal);

    END; / PRINT g_nome g_sal

  • 2. Execute o bloco

    SQL> @ c:\usa_proc.sql

    3. Resultado:

    digite o cdigo do funcionrio..... 7934 digite o percentual de aumento..... 10 Procedimento PL/SQL concludo com sucesso.

    Exemplo 3: Este exemplo utiliza a procedure formata_fone (que opera com parmetros IN OUT). Digite no prompt do SQL:

    Variable g_fone varchar2(15) Begin :g_fone := 01150819700; end; / Print g_fone Execute formata_fone(:g_fone) Print g_fone

    1.5.6. Passagem de Parmetros A passagem de parmetros pode ser feita de trs maneiras:

    Por posio: Os parmetros reais so listados de acordo com a ordem dos parmetros for-mais.

    Por identificao: Os parmetros reais so precedidos da identificao do parmetro for-mal, podendo ser listados arbitrariamente.

    Combinada: Os parmetros passados por posio devem ocupar os primeiros lugares da lista.

    Exemplo:

    CREATE OR REPLACE PROCEDURE incluir_dept (p_nome in dept.dname%type default sem nome ainda, p_loc in dept.loc%type default NC)

    is

    BEGIN Insert into dept(deptno, dname, loc) values(deptno_seq.nextval, p_nome, p_loc); END incluir_dept; /

    A seguir so exemplificadas as maneiras possveis de passagem de parmetros para a utilizao da procedure incluir_dept

    Por posio: SQL> EXECUTE incluir_dept; o prximo valor da sequence e os valores default se-ro includos seguindo a ordem de declarao dos parmetros formais.

  • SQL> EXECUTE Incluir_dept(R H, SC); os parmetros reais sero passados para os parmetros formais de acordo com a ordem de declarao dos parmetros for-mais.

    Por identificao: SQL> EXECUTE Incluir_dept( p_loc => SP, p_nome => Treinamento); os par-metros reais so precedidos da identificao dos parmetros formais e do sinal de atribuio =>

    Por combinao: SQL> EXECUTE Incluir_dept(p_loc => RJ); os parmetros que no esto listados recebero os valores defaut.

    Resultado: SQL> select * from dept; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING 12 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON 1 sem nome ainda NC 3 R H SC 4 Treinamento SP 5 sem nome ainda RJ 8 linhas selecionadas.

    1.5.7. Aninhamento de procedimentos (subprocedimentos) Pode-se criar um procedimento dentro de outro procedimento, este recurso chamado, tambm, de procedimentos em nveis. O exemplo a seguir cria a procedure exemplo_sub, nesta procedure est sendo criada uma outra procedure (log_usurio). Note que logo aps a clusula IS j indi-cada a sub procedure, somente aps a sua declarao completa que o corpo da procedure princi-pal declarado.

    CREATE OR REPLACE PROCEDURE exemplo_sub3(p_id in EMPR_NUME_NR%type) IS

    PROCEDURE log_usuario IS BEGIN

    Insert into log_tabela (user_id, log_data) Values(user, sysdate);

    END log_usuario; BEGIN Delete from EMPR Where EMPRno = p_id; END exemplo_sub;

    Log_usuario;

    / A procedure principal (exemplo_sub) utiliza a sub procedure (log_usurio)., neste caso a tabela log_tabela ir guardar a identificao do usurio e a data da operao pois a procedure principal faz uma excluso na tabela EMPR. 3 No esquea de criar a tabela para executar o exemplo: Create table log_tabela (user_id varchar2(10), log_data date);

  • Utilizao: SQL> execute exemplo_sub(7934); Procedimento PL/SQL concludo com sucesso. SQL> select * from log_tabela;

    USER_ID LOG_DATA ---------- -------- SCOTT 29/04/04 1.6. Funes As funes so muito semelhantes aos procedimentos, o que as difere, do ponto de vista estrutu-ral, a incluso da clusula return. A clusula return tambm implementa a diferena conceitual entre as procedures e as functions, isto , nas funes existe a obrigatoriedade de um retorno ro-tina chamadora, pode-se dizer que uma funo chamada como parte de uma expresso. Sintaxe:

    CREATE [ OR REPLACE] FUNCTION nome_funo [parmetro [in] tipo_parmetro, ... return tipo_do_retorno

    {IS ou AS} BEGIN corpo_da_funo END nome_funo;

    onde:

    Create or replace instruo para criao ou substituio do procedimento Nome_procedimento nome que ser dado ao procedimento parmetro [parmetro [in] nome do parmetro que poder ser somente para entra-

    da Tipo_parmetro tipo de dado que o parmetro poder aceitar return tipo_do_retorno Indica o retorno do controle a rotina chamadora com o

    valor que ser devolvido IS ou AS tem a mesma funo e indicam o bloco que estar asso-

    ciado ao procedimento, substitui a palavra reservada DECLARE.

    BEGIN corpo_do_procedimento END respectivamente o incio do bloco, o conjunto de instru-es do procedimento e o final do bloco.

    Exemplos:

    CREATE OR REPLACE FUNCTION descobrir_salario (p_id in EMP.EMPRno%type)

    return number IS

    vBEGIN

    _salario EMPR.sal%type := 0;

    Select sal into v_salario From EMPR Where EMPRno = p_id;

  • Return v_salario; End descobrir_salario; /

    Utilizao:

    SQL> variable g_sal number SQL> execute :g_sal := descobrir_salario(7900) SQL> print g_sal

    ATENO: Uma funo que contm instrues DML no pode ser utilizada no SQL em operaes DML. O exemplo a seguir ilustra est situao:

    CREATE OR REPLACE FUNCTION exemplo_dml (p_sal number)

    return number IS BEGIN Insert into EMPR(EMPR_NUME_NR, EMPR_NOME_DS, sal, hiredate, deptno) Return (p_sal + 300);

    Values(37, Sandra, p_sal, sysdate, 15);

    End exemplo_dml; /

    Utilizao:

    SQL> Update EMPR set sal = exemplo_dml(5000) Where EMPRno = 7900;

    Erro ocasionado:

    Update EMPR set sal = exemplo_dml(5000) * ERRO na linha 1: ORA-04091: a tabela SCOTT.EMP mutante; talvez o gatilho/funo no possa localiz-la ORA-06512: em "SCOTT.EXEMPLO_DML", line 6

    1.7. Resumo das diferenas entre procedure e function Procedure Function chamada em uma declarao SQL, blocos PL/SQL ou por uma aplicao

    chamada como parte de uma expresso

    No contm a clausula return no cabealho Contm a clausula return no cabealho Pode retornar nenhum, um ou vrios valores Retorna somente um valor Pode devolver um retorno rotina chamadora Retorna obrigatoriamente um valor para a rotina

    chamadora. 1.8. Trigger So blocos PL/SQL ou Procedures PL/SQL associadas tabelas, vises, esquemas ou bancos de dados. So disparados automaticamente antes ou depois da ocorrncia de um evento. Podem ser classificados em:

    Trigger de aplicao disparado quando evento envolve uma aplicao em parti-cular, este tpico no ser explorado.

  • Trigger de banco disparado quando ocorre uma operao DML para insero, alterao ou excluso de dados ou quando ocorre um evento associado ao banco, como exemplo o efetuar logon de um usurio. Podem ser implantados, entre outros, para:

    o Implantao de regras de negcios o Manuteno da integridade referencial o Implantao de segurana o Manuteno de um registro histrico das alteraes o Gerao de valores de coluna, incluindo valores de chave primria o Replicao de dados

    Sintaxe: CREATE [OR REPLACE] TRIGGER [esquema.]nome_trigger {BEFORE ou AFTER} [evento]ON [esquema.]tabela_nome [referencing Old as valor_anterior ou NEW as valor_novo) {nvel de linha ou nvel de instruo} [WHEN (condio)]] DECLARE BEGIN corpo_trigger END; / onde:

    Create or Replace Trigger instruo para criao ou substituio do Trigger

    Esquema Nome do esquema ao qual pertence o objeto

    Nome_trigger Identificador do trigger

    Before Indica que a execuo do trigger ser antes da realizao do evento

    After Indica que a execuo do trigger ser depois da realizao do evento

    evento Define qual o tipo de instruo que ir provocar o disparo do trigger. As instrues possveis so insert, update ou delete.

    On tabela_nome Indica a tabela que est associada instruo

    Referencing Old as valor_anterior ou NEW as valor_novo

    Especifica os identificadores das variveis que iro armaze-nar os valores antigos e novos. Old e New so pseudo-colunas que auxiliam na manipulao das linhas afetadas.

    Nvel de linha disparado uma vez para cada linha afetada pela instruo identificado por FOR EACH ROW

    Nvel de instruo disparado antes ou depois da instruo

    When condio S pode ser utilizada em trigger de linha. Indica que a trig-ger ser disparada somente quando a condio for verda-deira.

  • Exemplo 1: Criar um trigger para no permitir a insero ou alteraes da coluna salrio para va-lores superiores a 15000, caso o cargo do funcionrio no seja Presidente ou Vendedor. SQL> CREATE OR REPLACE TRIGGER restringe_salrio 2 BEFORE Insert or Update OF sal ON Scott.emp 3 FOR EACH ROW 4 BEGIN 5 If not (:new.job in('PRESIDENT', 'SALES')) 6 And :new.sal > 15000 7 Then 8 RAISE_APPLICATION_ERROR(-20202, 'O funcionrio no pode ter

    este aumento de salrio'); 9 END IF; 10 END; 11 / Quando um usurio tentar realizar uma operao de insero ou alterao que infrinja as regras definidas no trigger para o valor de salrio, a mensagem de erro ser apresentada conforme e-xemplo a seguir: SQL> insert into sCOTT.emp(EMPR_NUME_NR, EMPR_NOME_DS, EMPR_SERV_DS, sal, deptno) values 2* (135, 'MARCOS', 'CLERK', 15010, 10) * ERRO na linha 1: ORA-20202: O funcionario n?o pode ter este aumento de salario ORA-06512: em "SYS.RESTRINGE_SALARIO", line 5 ORA-04088: erro durante a execuc?o do gatilho 'SYS.RESTRINGE_SALARIO' ATENO: Os triggers no podem emitir commit ou rollback e no podem conter variveis Long ou Long raw

    Exemplo 2: Criar um trigger para no permitir a insero de funcionrios fora do horrio comercial SQL> CREATE OR REPLACE TRIGGER seguro_emp 2 BEFORE INSERT ON SCOTT.EMP 3 BEGIN 4 IF(TO_CHAR(SYSDATE, 'DY') IN ('SAT','SUN')) OR 5 (TO_CHAR(SYSDATE, 'HH24:MI') 6 NOT BETWEEN '08:00' AND '18:00') 7 THEN RAISE_APPLICATION_ERROR(-20500, 'Inseres de funcionrios so-

    mente no horrio comercial'); 8 end if; 9 end; 10 / A tentativa de inserir novos funcionrios fora do horrio previsto resultara no erro a seguir: SQL> insert into SCOTT.emp(EMPR_NUME_NR, EMPR_NOME_DS, sal, deptno) 2 values(7935, 'SANDRA', 1203, 10); insert into SCOTT.emp(EMPR_NUME_NR, EMPR_NOME_DS, sal, deptno) * ERRO na linha 1: ORA-20500: Inserc?es de funcionarios somente no horario comercial ORA-06512: em "SYS.SEGURO_EMP", line 5 ORA-04088: erro durante a execuc?o do gatilho 'SYS.SEGURO_EMP' Nos exemplos 1 e 2 o trigger disparado sempre antes da ao ser concretizada, este um re-curso til para fazer validaes, j no exemplo 3 apresentado um trigger disparado depois de um evento, este recurso til para fazer auditoria, por exemplo.

  • Exemplo: Criar um trigger para registrar as alteraes realizadas em uma tabela, valores antigos e novos, os dados do usurio que realizou a alterao e a data da ocorrncia: CREATE OR REPLACE TRIGGER auditar_emp AFTER DELETE OR INSERT OR UPDATE On Scott.emp FOR EACH ROW BEGIN INSERT INTO table_aud_emp(user_name, data,antigo_nome, novo_nome, anti-go_salario, novo_salario) values (user, sysdate, :old.ename,:new.ename,:old.sal, :new.sal); end; / Aps a realizao de qualquer operao DML a tabela de auditoria tabela_aud_emp receber um registro com as informaes do autor e data da operao, valores anteriores e valores atuais para nome e salrio do funcionrio, conforme o resultado apresentado a seguir: SQL> insert into SCOTT.emp(EMPR_NUME_NR, EMPR_NOME_DS, sal, deptno) 2 values(7935, 'SANDRA', 1203, 10); SQL> update scott.emp 2 set sal = 1300 3 where EMPR_NOME_DS = 'SANDRA'; Resultado: SQL> select * from table_aud_emp; USER_NAME DATA ID ANTIGO_NOME NOVO_NOME ANTIGO_SALARIO NOVO_SALARIO SYS 05/05/04 SANDRA 1203 SYS 05/05/04 SANDRA SANDRA 1203 1300 ATENO: Old e New so identificadores utilizados somente em triggers de linha, deve-se utilizar o prefixo : e fazer referncia coluna, por exemplo :old.ename. A tabela apresentada a seguir mostra os valores assumidos para :old e :new para cada evento: Evento :old :new INSERT No deve ser definido, Todas as

    colunas contm nulos. Novos valores que sero inseridos

    UPDATE Valores das colunas antes da atu-alizao (antigos)

    Valores das colunas aps a atualizao (novos)

    DELETE Valores das colunas antes da ex-cluso

    No deve ser definido, todas as colunas contero nulos.

    Select trigger_type, table_name, triggering_event From user_triggers Where...

  • Para saber mais consulte: Livros: Autor Ttulo Urman, Scott Urman, Scott, Oracle 8 Programao PL/SQL, McGraw Hill (1999) Oliveira, Celso H. Poderoso de

    Oliveira, Celso H. Poderoso de, Oracle 8i Pl/Sql - Guia De Consul-ta Rapida, Novatec, 2000

    Morelli, Eduardo Terra Morelli, Eduardo Terra, Oracle 8i Fundamental SQL, PL/SQL e Administrao, Editora rica, 2000

    SILBERSCHATZ, Abraham, KORTH, Henry F. e SUDASRSHAN, S.,

    Sistema de Banco de dados. So Paulo: Makron Books, 1999

    Oracle8i Administrao de Bancos de Dados. Rio de Janeiro: Editora Cincia Moderna

    Sites: Oracle http://otn.oracle.com/sample_code/tech/pl_sql/index.html imasters http://www.imasters.com.br SLQMagazine http://www.sqlmagazine.com.br Jose Valter http://josevalter.com.br/download/sql/Dicas%20Oracle%20SQL.PD

    FStanford University http://www-db.stanford.edu/~ullman/fcdb/oracle/or-

    plsql.html#variables%20and%20typesOracle http://www.orafaq.com/faqplsql.htm#WHATOracle http://otn.oracle.com/sample_code/tech/pl_sql/index.html imasters http://www.imasters.com.br SLQMagazine http://www.sqlmagazine.com.br

    i Puga, Sandra, Rissetti, Gerson ...

    APOSTILA DEORACLE PL/SQL PL/SQL1.1. Blocos Annimos1.1.1. Operadores e delimitadores1.1.2. Variveis1.1.3. Tipos de Variveis1.1.3.1 Tipos de Dados Escalares

    1.1.4. Variveis de Substituio1.1.5. Variveis de ligao1.1.6. Instrues SELECT em PL/SQL1.1.7. Aninhamento de blocos e Escopo das variveis1.1.8. Insero de Dados1.1.9. Atualizando Dados1.1.10. Excluso de Dados1.1.11. Controle de Transaes

    1.2. Estruturas de Controle1.2.1. Estruturas de seleo1.2.2. Estruturas de repetio (Loop) 1.2.2.1 Loop BsicoLoop FORLoop WHILE

    1.2.3. Loops e Labels Aninhados

    1.3. Cursores1.3.1. Cursores Explcitos1.3.1.1 Declarao de cursores explcitosAbertura do Cursor1.3.1.3 Recuperao das linhas do Cursor1.3.1.4 Fechamento de Cursor

    1.3.2. Cursores de Atualizao1.3.3. Variveis de Cursores

    1.4. Tratamento de Excees1.4.1. Excees pr-definidas nomeadas1.4.2. Excees nomeadas pelo desenvolvedor e associadas a cdigos de erro :

    1.5. Procedimentos1.5.1. Utilizando parmetros de entradaA procedure reajuste recebe os parmetros v_cdigo e v_porcentagem cujos valores sero utilizados para alterao de um registro na tabela EMPR.

    ISBEGIN1.5.2. Utilizando parmetros de sada1.5.3. Utilizando parmetros de entrada e sada1.5.4. Visualizao de erros de compilao1.5.5. Utilizao de procedimentos1. Editar as instrues em um arquivo com extenso sqlSQL> edit usa_proc.sql1.5.6. Passagem de ParmetrosisBEGIN

    1.5.7. Aninhamento de procedimentos (subprocedimentos)ISBEGIN

    USER_ID LOG_DATA

    1.6. FunesISBEGIN

    1.7. Resumo das diferenas entre procedure e function1.8. Trigger