02_-_PLSQL (1)

Embed Size (px)

Citation preview

  • 5/20/2018 02_-_PLSQL (1)

    1/164

    PL/SQL

  • 5/20/2018 02_-_PLSQL (1)

    2/164

    Histrico Desenvolvida pela Oracleem 1980, inicialmente sendo umalinguagem puramente procedural

    Atravs de um banco de dados Oracleimplementa umalinguagem de programao interpretada que proporciona um

    ambiente independente de sistema operacional

    Na estratgia de compilao interpretada cada programa escritoem PL/SQL compilado numa forma intermediria. Estechamado de Machine Readable Code(Mcode)Vantagem?

    O Mcode armazenado no dicionrio de dados do banco dedados e interpretado no run time

    Prof. Arquimedes Lima 2

  • 5/20/2018 02_-_PLSQL (1)

    3/164

    Histrico Desde a verso 10g a compilao deixou de ser interpretada

    para uma compilao nativa. Questo: A Oracle eliminou obenefcio de ser independente de sistema operacional?

    Ento qual a justificativa para compilao nativa?

    A partir da verso Oracle 9i, Release 9 a linguagem PL/SQLdeixou de ser puramente procedural comtemplando osconceitos de programao orientada objetos

    possvel estender as funcionalidades da linguagemescrevendo bibliotecas externas em C, C++ e Java. As rotinasem Javapodem ser armazenadas no prprio Databasecomexceo da verso Express Edition(XE)

    Prof. Arquimedes Lima 3

  • 5/20/2018 02_-_PLSQL (1)

    4/164

    Caractersticas

    Linguagem utilizada para programao de servidores de banco dedados Oracle

    Adicionado no Oracle 6

    No possui recursos de interface (comunicao com usurios) So definidos para realizar operaes especficas sobre os dados

    Oferece uma maior flexibilidade na manipulao dos dados atravs damistura dos comandos SQL com a linguagem PL/SQL

    Apresentam-se como:

    Stored Procedure Stored Function

    Triggers

    Pacotes (Packages)

    Blocos annimos

    Prof. Arquimedes Lima 4

  • 5/20/2018 02_-_PLSQL (1)

    5/164

    Arquitetura

    Linguagem de programao case-insensitive, assim como SQL

    Baseada no conceito de programao estruturada, tipos de

    dados estticos, programao modularizada, gerenciamento deexcees, programao paralela

    Adota os mesmos operadores, delimitadores de strings e tiposde dados declarativos do Pascal

    Os tipos de dados declarativos so ditos fortes (strongdatatypes) pois no podem ter o tipo de dado modificado emmodo run time

    Prof. Arquimedes Lima 5

  • 5/20/2018 02_-_PLSQL (1)

    6/164

    Arquitetura

    A linguagem PL/SQL suporta tipos de dados dinmicos

    considerada como uma linguagem que segue o modelo

    objeto relacional, tambm conhecido como modelo relacionalestendido

    Toda vez que o usurio conecta no banco de dados atravs deuma ferramenta cliente, a exemplo do SQL Plus, uma nova

    sesso criada e nesta possvel executar sentenas em SQLou rotinas escritas em PL/SQL

    Prof. Arquimedes Lima 6

  • 5/20/2018 02_-_PLSQL (1)

    7/164

    Arquitetura

    Prof. Arquimedes Lima 7

  • 5/20/2018 02_-_PLSQL (1)

    8/164

    Vantagens

    Melhor Performance

    Boa produtividade

    Possibilidade de definir as regras de negcio no servidor de

    banco de dados Integrao com os recursos do Oracle

    Centralizao da lgica de negcio

    Equivalentes em outros SGBDs: Transcation SQLSQL Server PL/PgSQLPostgreSQL

    Prof. Arquimedes Lima 8

  • 5/20/2018 02_-_PLSQL (1)

    9/164

    Blocos Estruturados Com a linguagem PL/SQL possvel escrever blocos que

    chamamos de annimos (unnamed blocks) que podem serutilizados em vrias situaes: Execuo de scripts de carga dedados, processamento de rotinas avulsasTem como objetivoprincipal executar tarefas avulsas.

    Prottipo de um bloco annimo:

    Prof. Arquimedes Lima 9

  • 5/20/2018 02_-_PLSQL (1)

    10/164

    Al mundo!

    SETSERVEROUTPUTON;

    BEGINdbms_output.put_line('Hello World.');

    END;

    /

    Prof. Arquimedes Lima 10

  • 5/20/2018 02_-_PLSQL (1)

    11/164

    Outro exemplo ...

    SETSERVEROUTPUTON;

    DECLARE

    v_nomeVARCHAR2(30);BEGIN

    v_nome := '&input';

    dbms_output.put_line('Hello '||

    v_nome );END;

    /

    Prof. Arquimedes Lima 11

  • 5/20/2018 02_-_PLSQL (1)

    12/164

    Blocos nomeados - FunesFUNCTIONfunction_name

    [( parameter1 [IN][OUT] sql_data_type,

    , parameter2 [IN][OUT] sql_data_type,

    , parameter(n+1) [IN][OUT] sql_data_type )]

    RETURN[ sql_data_type ]IS

    -- sentenas de declarao

    BEGIN

    -- sentenas de execuo

    [EXCEPTION]

    -- sentenas de tratamento de excees

    END;

    Prof. Arquimedes Lima 12

  • 5/20/2018 02_-_PLSQL (1)

    13/164

    Exemplo Funocreateor replace function

    f_obter_desconto( p_uf char,

    p_salario number ) returnnumber

    is

    v_perc_desc number(3,2);

    beginifp_uf in ( 'SE', 'BA', 'AL', 'PE' ) then

    v_perc_desc := 0.05;

    elsifp_uf in( 'RJ', 'SP', 'MG', 'RS', 'PR' ) then

    v_perc_desc := 0.07;

    else

    v_perc_desc := 0.04;

    end if;

    return trunc( p_salario * v_perc_desc, 2 );

    end;

    Prof. Arquimedes Lima 13

  • 5/20/2018 02_-_PLSQL (1)

    14/164

    Blocos nomeados - ProcedimentosPROCEDUREprocedure_name

    [( parameter1 [IN][OUT] sql_data_type,

    , parameter2 [IN][OUT] sql_data_type,

    , parameter(n+1) [IN][OUT] sql_data_type )]

    IS-- sentenas de declarao

    BEGIN

    -- sentenas de execuo

    [EXCEPTION]

    -- sentenas de tratamento de excees

    END;

    Prof. Arquimedes Lima 14

  • 5/20/2018 02_-_PLSQL (1)

    15/164

    Exemplo Procedimentocreate or replace procedure

    p_calc_desconto( p_uf char,

    p_salario number,

    p_desc out number)

    is

    v_perc_desc number(3,2);

    begin

    ifp_uf in( 'SE', 'BA', 'AL', 'PE' ) then

    v_perc_desc := 0.05;

    elsifp_uf in( 'RJ', 'SP', 'MG', 'RS', 'PR' ) then

    v_perc_desc := 0.07;

    else

    v_perc_desc := 0.04;

    end if;

    p_desc := trunc( p_salario * v_perc_desc, 2 );

    end; Prof. Arquimedes Lima 15

  • 5/20/2018 02_-_PLSQL (1)

    16/164

    Exemplo Exceo Tratamento de exceo quando o nome maior que a varivel

    SETSERVEROUTPUTON;

    DECLARE

    v_nomeVARCHAR2(10);

    BEGIN

    v_nome := '&input';

    dbms_output.put_line('Hello '|| v_nome );

    EXCEPTIONWHENothers THEN

    dbms_output.put_line(SQLERRM);

    END;

    /

    Prof. Arquimedes Lima 16

  • 5/20/2018 02_-_PLSQL (1)

    17/164

    Variveis, Atribuies e

    Operadores Os nomes das variveis devem iniciar obrigatoriamente com

    letras, deve conter somente caracteres alfabticos, nmeros eos caracteres especiais $, _, #

    Em linhas gerais uma varivel tem o escopo local. A exceodesta regras so os blocos annimos alinhados que asvariveis ficam acessveis nas sub-rotinas

    Vejamos o exemplo:DECLARE

    v_numeroNUMBER;BEGIN

    v_numero := 1;

    END;

    / Prof. Arquimedes Lima 17

  • 5/20/2018 02_-_PLSQL (1)

    18/164

    Variveis, Atribuies e

    Operadores Quando o valor declarado sem especificar o valor inicial o

    valor considerado NULL, conforme exemplo:DECLARE

    v_numeroNUMBER;

    BEGIN

    ifv_numero IS NULLthen

    dbms_output.put_line( 'Nmero nulo' );

    end if;

    v_numero := 1;

    ifv_numero IS NOT NULLthen

    dbms_output.put_line( 'Nmero no nulo' );

    end if;

    END;

    / Prof. Arquimedes Lima 18

  • 5/20/2018 02_-_PLSQL (1)

    19/164

    Tipos de Variveis

    VARCHAR2, NUMBER, CHAR e DATE

    PLS_INTEGER, BINARY_FLOAT,BINARY_INTEGER

    BOOLEAN e PLS_INTEGER

    TABLE, VARRAY e RECORD

    Prof. Arquimedes Lima 19

  • 5/20/2018 02_-_PLSQL (1)

    20/164

    Tipos de Variveis

    CHAR(TAM)

    Literal de armazenamento fixo. O Seu tamanho pode variar de 1 a2000.

    VARCHAR2(TAM)

    Literal de armazenamento varivel. O tamanho mximo pode variarde 1 a 4000.

    NUMBER(P,S)

    Armazenamento de ponto flutuante entre 1 x 10-130 e 9.99999 x10125. p = indica a quantidade total de dgitos, incluindo as casas

    decimais - s: nmero de dgitos decimais DATE

    Armazenamento de datas

    Prof. Arquimedes Lima 20

  • 5/20/2018 02_-_PLSQL (1)

    21/164

    Tipos de Variveis

    BINARY_INTEGER

    Valor inteiro que varia -2-31 a 231 BOOLEAN

    Valores lgicos ( TRUE, FALSE ) VARRAYS

    Vetores IS TABLE OF

    Tabela hash

    IS RECORD Registros

    PLS_INTEGER

    -2147483647 e 2147483647

    Prof. Arquimedes Lima 21

  • 5/20/2018 02_-_PLSQL (1)

    22/164

    Tipos de Variveis

    BINARY_FLOAT

    Representao de 32 bits

    BINARY_DOUBLE

    Representao de 64 bits

    Prof. Arquimedes Lima 22

  • 5/20/2018 02_-_PLSQL (1)

    23/164

    Operadores Aritmticos

    Adio ( + ) e Subtrao ( - )

    Multiplicao ( * ) e Diviso ( / )

    Concatenao( || )

    Comparao Bsica

    Igualdade ( = ) e Diferena ( , != )

    Maior ( > ) e Maior ou igual ( >= )

    Menor ( < ) e Menor ou Igual (

  • 5/20/2018 02_-_PLSQL (1)

    24/164

    Operadores

    IN

    Verifica se o contedo de uma varivel est presente emuma dada coleo

    cod_curso IN ( 2, 5, 7, 9, 10 )

    LIKE Avalia se o contedo de uma varivel segue o padro

    definido por uma literal

    Os caracteres de substituio so:

    %, para uma cadeia de caracteres

    _, para um caracter

    nome like 'Ana%'

    Prof. Arquimedes Lima 24

  • 5/20/2018 02_-_PLSQL (1)

    25/164

    Operadores

    SOME e ANY

    Deve ser utilizado com um dos seguintes operadores: =, >,= e all( 6, 7, 9 )

    Prof. Arquimedes Lima 25

  • 5/20/2018 02_-_PLSQL (1)

    26/164

    Operadores

    Operadores lgicos

    NOT, AND, OR

    Precedncia

    Operadores multiplicativos ( *, / ) Operadores aditivos ( +, - )

    Operadores de comparao ( =, >, is null, ... )

    NOT

    AND OR

    Os parnteses podem ser utilizados para alterar aprecedncia de avaliao das expresses

    Prof. Arquimedes Lima 26

  • 5/20/2018 02_-_PLSQL (1)

    27/164

    Principais Funes Numricas

    ABS( n )

    Obtm o mdulo de um nmero

    Ceil( n )

    Retorna o maior inteiro maior ou igual a n EXP( n )

    Retorna o valor de e (2.71828183) elevado a n

    Floor( n )

    Retorna o menor inteiro menor ou igual a n LN( n )

    Retorna o logaritmo natural de n

    Prof. Arquimedes Lima 27

  • 5/20/2018 02_-_PLSQL (1)

    28/164

    Principais Funes Numricas

    LOG( b, n )

    Retorna o logaritmo de n na base b

    MOD( n, d )

    Obtm o resto da diviso de n por b POWER( n, m )

    Recupera o valor de n elevado a m

    ROUND( n, d )

    Arredonda o valor de n na casa decimal d O valor default zero

    O valor de d pode ser negativo

    Prof. Arquimedes Lima 28

  • 5/20/2018 02_-_PLSQL (1)

    29/164

    Principais Funes Numricas SQRT( n )

    Obtm a raiz quadrada de n

    TRUNC( n, m )

    Trunca o valor de na na casa decimal definida por m

    O valor default para m zero

    O valor de m pode ser negativo

    SIN( n )

    Seno de n

    COS( n )

    Cosseno de n TAN( n )

    Tangente de n

    Prof. Arquimedes Lima 29

  • 5/20/2018 02_-_PLSQL (1)

    30/164

    Principais Funes Literais

    ASCII( c )

    Recupera o cdigo ascii de um determinado caractere

    CHR( n )

    Mapeia o caractere ascii referente ao nmero n CONCAT( c1, c2 )

    Retorna o resultado da concatenao de c1 com c2

    INITCAP( c )

    Retorna a literal c com todas as iniciais de palavras emletras maisculas e o restante em letras minsculas

    Prof. Arquimedes Lima 30

  • 5/20/2018 02_-_PLSQL (1)

    31/164

    Principais Funes Literais

    INSTR( c1, c2, n, m )

    Recupera a posio, considerando que a primeira letra aposio 1, onde c2 aparece em c1

    O parmetro n opcional e indica a posio de incio dabusca em c1

    O parmetro m determina qual a ocorrncia de c2 em c1deve ser considerada

    Os valores default de n e m so 1

    A expresso instr( nome, 'es', 4, 2 ) indica que deve serretornada a posio da segunda ocorrncia da literal 'es' apartir da quarta posio do contedo da varivel nome

    Prof. Arquimedes Lima 31

  • 5/20/2018 02_-_PLSQL (1)

    32/164

    Principais Funes Literais

    LOWER( c ) e UPPER( c )

    Converte todas as letras da literal c para minscula (lower)ou maisculas (upper)

    LPAD( c1, tam, c2 ) e RPAD( c1, tam, c2 )

    Retorna a literal c1 preenchida esquerda (lpad) ou direita(rpad) com a literal c2 at o tamanho definido peloparmetro tam

    O parmetro c2 opcional, e quando no informado considerado o espao em branco

    LTRIM( c1, c2 ) e RTRIM( c1, c2 ) Retorna a literal c1 retirando as ocorrncia de c2 esquerda

    (ltrim) ou direita (rtrim) c2 opcional sendo que o default espao em branco

    Prof. Arquimedes Lima 32

  • 5/20/2018 02_-_PLSQL (1)

    33/164

    Principais Funes Literais

    LENGTH( c1 )

    Retorna o tamanho da literal c1

    REPLACE( c1, c2, c3 )

    Retorna o resultado da substituio de todas as ocorrnciasde c2 por c3 em c1

    SUBSTR( c1, m, n )

    Recupera uma substring de c1 iniciada na posio m comtamanho n

    n opcional, e quando omitido considerada toda a literal apartir da posio m

    Prof. Arquimedes Lima 33

  • 5/20/2018 02_-_PLSQL (1)

    34/164

    Principais Funes de Data

    ADD_MONTHS( d, n )

    Retorna uma data que resultado da adio de n meses data d

    MONTHS_BETWEEN( d1, d2 )

    Obtm o nmero de meses existente entre as datas d1 e d2 SYSDATE

    Retorna a data atual do sistema, incluindo hora, minuto esegundo

    TRUNC( d )

    Retorna a data d sem as informaes de hora, minuto esegundos

    Prof. Arquimedes Lima 34

  • 5/20/2018 02_-_PLSQL (1)

    35/164

    Principais Funes de Converso

    TO_DATE( lit, fmt )

    Converte a literal lit para o tipo data utilizando o formatoespecificado por fmt

    TO_CHAR( d, fmt )

    Converte uma data para uma literal com o formato definidopor fmt

    TO_CHAR( n, fmt )

    Converte um nmero para uma literal com o formatodefinido por fmt

    TO_NUMBER ( l, fmt )

    Converte uma literal para um valor numrico utilizando comoformato de converso o parmetro fmt

    Prof. Arquimedes Lima 35

  • 5/20/2018 02_-_PLSQL (1)

    36/164

    Principais Funes de Converso Se o padro de converso no for informado, o Oracle utilizar

    o formato default da seo do usurio Principais padres para nmero

    Dindica o separador de milhar de um nmero

    Gindica o separador decimal de um numero

    0define que um nmero deve ser retornado 9indica que um nmero pode ser retornado

    $ - define que o smbolo deve ser retornado

    Ldefine o smbolo local para moeda

    Exemplos:

    Prof. Arquimedes Lima 36

    selectto_char(1210.73, '9G999D00') formato_numerico

    fromdual;

    selectto_char(1210.73, 'L9G999D00') formato_moeda

    fromdual;

    selectto_char(21, '000099') zero_esquerda

    fromdual;

  • 5/20/2018 02_-_PLSQL (1)

    37/164

    Principais Funes de Converso Principais padres para data

    DDDia com dois dgitos

    MMMs com dois dgitos

    YYYYAno com 4 dgitos

    HH24Hora com 2 dgitos (0..23) MIMinutos em 2 dgitos

    SSSegundos com 2 dgitos

    DDia da semana (1..7)

    DAYDescrio do dia MONTHDescrio do ms

    MONTrs letras iniciais do ms

    Ex.: 'DD/MM/YYYY HH24:MI:SS

    Prof. Arquimedes Lima 37

  • 5/20/2018 02_-_PLSQL (1)

    38/164

    lgebra com Datas

    A adio ou subtrao de nmeros inteiros a uma dataocasionam, respectivamente, o acrscimo ou decrscimos dedias data

    A subtrao de duas datas retorna o nmero de dias existentesentre elas

    Datas no podem ser multiplicadas ou divididas

    Adicionar 1 minuto a uma data equivale a adio de 1/1440 aela

    Adicionar 1 segundo a uma data equivale a adio de 1/86400a ela

    Prof. Arquimedes Lima 38

  • 5/20/2018 02_-_PLSQL (1)

    39/164

    Exemplos de Padres de Data

    Uma data formatada com ano em quatro dgitos, horas, minutose segundos

    DD/MM/YYYY HH24:MI:SS

    15/10/2012 13:22:30 Formatao para recuperar a descrio do ms, a palavra de,

    e o ano em quatro dgitos

    MONTH de YYYY

    ABRIL DE 2012

    Formato para obter o nmero do dia de uma data (1-Domingo,2-Segunda, etc ...)

    D

    Prof. Arquimedes Lima 39

  • 5/20/2018 02_-_PLSQL (1)

    40/164

    Funo para Mapeamento de Valores

    DECODE( var, val1, res1, ...,

    valN, resN, resDefault)

    Implementa uma condicional de uma linha

    Se o valor da varivel var for igual a val1, o resultado da funoser res1. Se o valor de var no coincidir com nenhum dosvalores, ser retornado o resultado padro (resDefault)

    O resultado padro opcional

    Exemplo

    DECODE( conceito, A, TIMO,B, BOM,

    C, REGULAR,

    RUIM )

    Prof. Arquimedes Lima 40

  • 5/20/2018 02_-_PLSQL (1)

    41/164

    Outras Funes GREATEST( arg1, arg2, arg3, ..., argn )

    Recupera o maior valor existente entre os argumentos

    LEAST( arg1, arg2, arg3, ..., argn )

    Recupera o menor valor existente entre os argumentos

    NVL( arg1, arg2 )

    Testa o valor de arg1 de modo que se o mesmo for nulo, afuno retorna o valor de arg2, caso contrrio, retorna oprprio valor de arg1

    USER

    Recupera o nome do usurio corrente

    Prof. Arquimedes Lima 41

  • 5/20/2018 02_-_PLSQL (1)

    42/164

    ValorDefault Exemplo 01

    DECLARE

    v_numNUMBER:= 1;

    BEGIN

    dbms_output.put_line( 'Valor padro --> '||

    v_num );

    END;

    Exemplo 02DECLARE

    v_numNUMBERDEFAULT 1;BEGIN

    dbms_output.put_line( 'Valor padro --> '||

    v_num );

    END;

    Prof. Arquimedes Lima 42

  • 5/20/2018 02_-_PLSQL (1)

    43/164

    Constantes

    DECLARE

    v_pi CONSTANT NUMBER:= 3.14;

    BEGIN

    dbms_output.put_line( 'PI --> '||v_pi );

    END;

    Prof. Arquimedes Lima 43

  • 5/20/2018 02_-_PLSQL (1)

    44/164

    Operadores Em suma os operadores so os mesmos utilizados na

    linguagem SQL (ser revisto posteriormente)

    A comparao de negao pode ser realizada de quatro formasdistintas: , !=, ~=, ^=

    DECLARE

    v_numNUMBER:= 1;

    BEGIN

    if v_num 2 then

    dbms_output.put_line( 'Diferente de 2' );

    end if;

    if v_num != 2 then

    dbms_output.put_line( 'Diferente de 2' );

    end if;

    END;Prof. Arquimedes Lima 44

  • 5/20/2018 02_-_PLSQL (1)

    45/164

    Estruturas de Controle

    Estruturas Condicionais

    IF ELSIF ELSE

    CASE

    Estruturas Iterativas

    FOR

    SIMPLE

    WHILE

    Prof. Arquimedes Lima 45

  • 5/20/2018 02_-_PLSQL (1)

    46/164

    Estruturas Condicionais(IF, CASE)

    Prof. Arquimedes Lima 46

  • 5/20/2018 02_-_PLSQL (1)

    47/164

    Sentena IF Possui dois subtipos

    IF THEN ELSE

    IF THEN ELSIF THEN ELSE

    Todas as sentenas IFso finalizadas com a palavrareservada END IF

    Assim como as sentenas CASE so finalizadas com a palavrareservada END CASE

    O ponto e vrgula sempre utilizado como finalizador de cadafrase

    Prof. Arquimedes Lima 47

  • 5/20/2018 02_-_PLSQL (1)

    48/164

    IFTHEN - ELSE

    Prottipo bsico

    IF[NOT] left_operand1 = right_operand1 [[AND|OR]

    [NOT] left_operand2 = right_operand2 [[AND|OR]

    [NOT] boolean_operand ]] THEN

    NULL;

    [ELSE]

    NULL;

    ENDIF;

    Prof. Arquimedes Lima 48

  • 5/20/2018 02_-_PLSQL (1)

    49/164

    ExemploDECLARE

    -- Varivel booleana (comentrio de uma linha)

    my_var BOOLEAN;

    BEGIN

    /* Utilizando a funo NVL

    (comentrio de mais de uma linha)*/

    IFNOTNVL(my_var,FALSE) THEN

    dbms_output.put_line('Valor no inicializado');

    ELSE

    dbms_output.put_line('Valor inicializado');

    END IF;

    END;

    Prof. Arquimedes Lima 49

  • 5/20/2018 02_-_PLSQL (1)

    50/164

    IFTHENELSIFTHEN - ELSE

    Prottipo bsico

    IF [NOT] left_operand1 > right_operand2 [AND|OR]

    NULL;

    ELSIF[NOT] left_operand1 = right_operand1 [[AND|OR][NOT] left_operand2 = right_operand2 [[AND|OR]

    [NOT] boolean_operand ]] THEN

    NULL;

    [ELSE]

    NULL;END IF;

    Prof. Arquimedes Lima 50

  • 5/20/2018 02_-_PLSQL (1)

    51/164

    Sentena CASE

    Funciona de forma anloga a sentena IF THEN ELSIFTHEN ELSE

    Existem dois tipos de sentena CASE

    Case simples (SIMPLE CASE) Neste caso, uma varivel escalar (seletora ou selector)

    utilizada para avaliao da expresso Case com pesquisa (SEARCHED CASE)

    Nesta segunda alternativa, utilizada uma expresso

    condicional para avaliao Veremos os exemplos a seguir ...

    Prof. Arquimedes Lima 51

  • 5/20/2018 02_-_PLSQL (1)

    52/164

    Sentena CASE

    Prottipo genrico da sentena CASE:

    CASE[ TRUE| [selector_variable]]

    WHEN[criterion1 | expression1] THEN

    criterion1_statements;

    WHEN[criterion2 | expression2] THEN

    criterion2_statements;

    WHEN[criterion(n+1) | expression(n+1)] THEN

    criterion(n+1)_statements;ELSE

    block_statements;

    END CASE;

    Prof. Arquimedes Lima 52

  • 5/20/2018 02_-_PLSQL (1)

    53/164

    SIMPLE CASE

    DECLARE

    selectorNUMBER:= 0;

    BEGIN

    CASEselector

    WHEN0 THEN

    dbms_output.put_line('Case 0!');

    WHEN1 THEN

    dbms_output.put_line('Case 1!');

    ELSEdbms_output.put_line('No localizado!');

    END CASE;

    END;

    Prof. Arquimedes Lima 53

  • 5/20/2018 02_-_PLSQL (1)

    54/164

    SEARCHED CASE - Exemplo

    BEGIN

    CASE

    WHEN(1 > 3) THEN

    dbms_output.put_line('Um maior do que trs');

    WHEN(3 < 5) THEN

    dbms_output.put_line('Trs menor do que cinco');

    WHEN(1 = 2) THEN

    dbms_output.put_line('Um igual a dois');

    ELSE

    dbms_output.put_line('Nenhuma das anteriores');

    END CASE;

    END;

    Prof. Arquimedes Lima 54

  • 5/20/2018 02_-_PLSQL (1)

    55/164

    Interao com SQLdeclare

    v_nome cursos_teste.nom_curso%type;

    v_qtd cursos_teste.qtd_cred%type;

    v_cod_curso number(5);

    begin

    v_cod_curso := 4;

    select nom_curso, qtd_cred into v_nome, v_qtd

    from cursos_teste

    where cod_curso >= v_cod_curso;

    dbms_output.put_line( v_nome||' - '|| v_qtd );

    exception

    whenno_data_found then

    raise_application_error( -20000, 'Curso informado no existe');

    whentoo_many_rows then

    raise_application_error( -20000, Vrias linhas selecionadas');

    end;

    Prof. Arquimedes Lima 55

  • 5/20/2018 02_-_PLSQL (1)

    56/164

    Interao com SQL

    Este exemplo demonstra a utilizao de um cursor implcito de umalinha

    Excees que eventualmente devem ser tratadas: NO_DATA_FOUND: Nenhuma linha retornada

    TOO_MANY_ROWS: Vrias linhas encontradas

    Algumas variveis podem auxiliar o desenvolvedor:

    Prof. Arquimedes Lima 56

  • 5/20/2018 02_-_PLSQL (1)

    57/164

    Exemplo

    declare

    i integer;

    begin

    select 1 into i from dual;

    ifsql%notfoundthen

    dbms_output.put_line( 'Nehuma informao encontrada' );

    elsifsql%foundthen

    dbms_output.put_line( 'Informao encontrada' );

    end if;

    dbms_output.put_line( 'Linhas retornadas = '||

    sql%rowcount);

    end;

    Prof. Arquimedes Lima 57

  • 5/20/2018 02_-_PLSQL (1)

    58/164

    Exemplo Cursor Implcito Vrias Linhas

    SET SERVEROUTPUT ON;

    BEGIN

    UPDATEcursos

    SETtot_cred = tot_cred + 20

    WHEREtot_cred between 100 and 450;

    IFSQL%FOUND THEN

    dbms_output.put_line('Updated ['||

    SQL%ROWCOUNT||']');

    ELSEdbms_output.put_line('Nothing updated!');

    ENDIF;

    END;

    Prof. Arquimedes Lima 58

  • 5/20/2018 02_-_PLSQL (1)

    59/164

    Estruturas Iterativas(FOR, SIMPLE, WHILE)

    Prof. Arquimedes Lima 59

  • 5/20/2018 02_-_PLSQL (1)

    60/164

    Sentena FOR

    O PL/SQLsuporta dois tipos de laos FOR:

    Laos numricos: A iterao feita sob determinado range

    Laos com cursores: A iterao feita a depender do

    nmero de linhas retornados por uma sentena SQL nocursor

    Nesta construo, podemos utilizar de forma combinada assentenas CONTINUEou EXIT, para respectivamente, pular e

    forar uma sada prematura do lao

    Prof. Arquimedes Lima 60

  • 5/20/2018 02_-_PLSQL (1)

    61/164

    Exemplo Lao Numrico (FOR)

    BEGIN

    FORi IN 1 .. 15 LOOP

    dbms_output.put_line( 'Valor indexado --> '||i );

    END LOOP;

    END;

    BEGIN

    FORi IN REVERSE 1 .. 15 LOOP

    dbms_output.put_line( 'Valor indexado --> '||i );END LOOP;

    END;

    Prof. Arquimedes Lima 61

  • 5/20/2018 02_-_PLSQL (1)

    62/164

    Lao com CURSOR (FOR)

    Prottipo

    FORi IN {cursor_name[(parameter1,

    parameter(n+1))] |

    (sql_statement)} LOOP

    -- Sentena

    END LOOP;

    Prof. Arquimedes Lima 62

  • 5/20/2018 02_-_PLSQL (1)

    63/164

    Exemplo Lao com CURSOR (FOR)

    DECLARE

    CURSORc IS

    SELECTu.cod_curso, u.nom_curso

    FROMacademico.cursos u ORDER BY 1;

    v_comp varchar2(50);

    BEGINFORi IN c LOOP

    v_comp := '';

    IFi.cod_curso = 35 THEN

    v_comp := 'CURSO INTEGRAL --------->';

    END IF;

    dbms_output.put_line( v_comp ||

    lpad( i.cod_curso,3, '0' ) ||

    '-' || i.nom_curso );

    ENDLOOP;

    END;Prof. Arquimedes Lima 63

  • 5/20/2018 02_-_PLSQL (1)

    64/164

    Cursor Implcito

    BEGIN

    FORi IN( SELECTcod_curso, nom_curso

    FROMacademico.cursos

    ORDERBYnom_curso ) LOOPdbms_output.put_line('['||i.cod_curso||'-'||

    i.nom_curso||']');

    ENDLOOP;

    END;

    Prof. Arquimedes Lima 64

  • 5/20/2018 02_-_PLSQL (1)

    65/164

    Operaes com CursoresDECLARE

    CURSORc IS

    SELECTcod_curso, nom_curso

    FROMacademico.cursos

    ORDER BY 1;

    v_linha c%rowtype;BEGIN

    OPENc;

    LOOP

    FETCHc INTOv_linha;

    EXIT WHEN c%NOTFOUND;

    dbms_output.put_line('['||v_linha.cod_curso||'-'||

    v_linha.nom_curso||']');

    END LOOP;

    CLOSE c;

    END;Prof. Arquimedes Lima 65

  • 5/20/2018 02_-_PLSQL (1)

    66/164

    Clusula WHILE com CursoresDECLARE

    CURSORc IS

    SELECTcod_curso, nom_curso

    FROMacademico.cursos

    ORDERBY1;

    v_linha c%rowtype;

    BEGIN

    OPENc;

    WHILEc%ISOPEN LOOP

    FETCHc INTOv_linha;

    IFc%NOTFOUND THEN

    CLOSEc;END IF;

    dbms_output.put_line('['||v_linha.cod_curso||'-'||

    v_linha.nom_curso||']');

    ENDLOOP;

    END; Prof. Arquimedes Lima 66

    SIMPLE / WHILE N i

  • 5/20/2018 02_-_PLSQL (1)

    67/164

    SIMPLE / WHILE NumricoDECLARE

    v_num pls_integer;BEGIN

    v_num := 1;

    WHILEv_num11 LOOP

    dbms_output.put_line('['||v_num||']');

    v_num := v_num + 1;ENDLOOP;

    dbms_output.put_line( '---- x ---- ');

    v_num := 1;

    loop

    dbms_output.put_line( '{'||v_num||'}' );

    v_num := v_num + 1;

    exit when v_num = 11;

    end loop;

    END; Prof. Arquimedes Lima 67

  • 5/20/2018 02_-_PLSQL (1)

    68/164

    Exerccio 1

    1. Faa um bloco annimo que liste todos os nmerosprimos pertencentes ao um intervalo fechado. Esteintervalo deve ser definido por duas constantes inteiras

    mod(a,b): resto da diviso inteira de a por b

    2. Faa um bloco annimo que, com base em uma string,separe valores pelo caracter ;, liste estes valores umpor linha (Ex: thiago;10;10/01/1970).length( string ): retorna a quantidade decaracteres de uma string

    Prof. Arquimedes Lima 68

  • 5/20/2018 02_-_PLSQL (1)

    69/164

    Tipos de Dados Compostos

    Existem dois tipos de dados compostos: Registrose Colees

    Os registrostipicamente possuem um conjuntos de elementosrelacionados, assim como tabelas do banco de dados

    Uma coleopode conter um conjunto de tipos de dados escalares,vetoriais, LOBs ou tipos de dados definidos pelo usurio

    Os registros so teis para trabalhar com cursores e colees

    A seguir veremos com maiores detalhes esses tipos de dadoscompostos

    Prof. Arquimedes Lima 69

    R i t (R d )

  • 5/20/2018 02_-_PLSQL (1)

    70/164

    Registros (Records)

    Um registro um tipo estruturado que contm uma lista de variveisque tipicamente possuem nomes e tipos de dados distintos

    Exemplo de registro explcito:DECLARE

    TYPEt_pessoa IS RECORD

    ( id number(5),

    cpf char(11),

    nome varchar2(60) );

    v_pes t_pessoa;

    BEGIN

    v_pes.id := 10;

    v_pes.cpf := 56947825414;

    v_pes.nome := Maria Jos;

    dbms_output.put_line( v_pes.id||;||v_pes.cpf||;||

    v_pes.nome );

    END;

    Prof. Arquimedes Lima 70

  • 5/20/2018 02_-_PLSQL (1)

    71/164

    Registros Implcitos Atravs de atributo %ROWTYPE possvel declarar um registro de

    forma implcita:DECLARE

    v_cur academico.cursos%rowtype;

    BEGIN

    v_cur.cod_curso := 26;

    v_cur.nom_curso := 'Cincia da Computao';

    v_cur.tot_cred := 300;

    v_cur.idt_prof := 3421;

    dbms_output.put_line(v_cur.cod_curso||';'||

    v_cur.nom_curso );

    END;

    Prof. Arquimedes Lima 71

  • 5/20/2018 02_-_PLSQL (1)

    72/164

    Colees

    As colees so compostas pelos vetorese listas

    A diferena essencial entre eles que os vetores utilizam indexadoresnumricos sequenciais, enquanto as listas podem utilizar indexadores

    numricos no sequenciais ou indexadores string

    Os vetores so caracterizados por serem populados densamente (jque so compostos por nmeros sequenciais, enquanto as listaspodem ser esparsadas viabilizando buracos (gaps) na sequncia que

    os indexa

    A Oracle suporta trs tipos de colees, so elesVARRAY, NESTEDTABLEeARRAY

    Prof. Arquimedes Lima 72

  • 5/20/2018 02_-_PLSQL (1)

    73/164

    Colees - VARRAY

    um vetor tradicional onde os elementos so do mesmo tipo de dadose utiliza indexadores numricos sequenciais

    O desenvolvedor deve utilizar mensurar, em tempo de declarao, otamanho do vetor

    Nesta coleo, no possvel incrementar o tamanho do vetor emtempo de execuo

    Tambm possvel inicializar o vetor com valores na declarao da

    coleo

    Deve ser utilizado quando o desenvolvedor sabe a priori exatamente aquantidade de elementos que ir precisar

    Prof. Arquimedes Lima 73

  • 5/20/2018 02_-_PLSQL (1)

    74/164

    Exemplo VARRAYDECLARE

    TYPEtipo_varray IS VARRAY(10) OF NUMBER;

    v_lista tipo_varray := tipo_varray(1,2,3,4,5,6,7,8,null);

    BEGIN

    FORi IN1 .. v_lista.COUNT LOOP

    dbms_output.put('['||v_lista(i)||']');

    END LOOP;

    dbms_output.new_line;

    dbms_output.put_line( 'Limite mximo do vetor:'||v_lista.LIMIT );

    dbms_output.put_line( 'Total de elementos: '||

    v_lista.COUNT );

    END; Prof. Arquimedes Lima 74

  • 5/20/2018 02_-_PLSQL (1)

    75/164

    Exemplo VARRAYDECLARE

    TYPEtipo_varray IS VARRAY(10) OF NUMBER;

    v_lista tipo_varray := tipo_varray();

    BEGIN

    v_lista.extend( v_lista.LIMIT);

    FORi IN1 .. 8 LOOP

    v_lista(i) := i;

    END LOOP;

    FORi IN1 .. v_lista.COUNTLOOP

    dbms_output.put('['||v_lista(i)||']');END LOOP;

    dbms_output.new_line;

    END;

    Prof. Arquimedes Lima 75

  • 5/20/2018 02_-_PLSQL (1)

    76/164

    ColeesNESTED TABLE Tambm utiliza como base indexadores sequenciais numricos

    A diferena com relao a coleo VARRAY est no fato que no preciso estabelecer a priori a quantidade de elementos necessria

    Desta forma, podendo ser dimensionada por demanda e em tempo deexecuo. So densamente populadas

    Deve ser utilizada quando o desenvolvedor no sabe, a princpio, da

    quantidade exata de elementos que ir necessitar no programa

    O DBA responsvel por definir o tamanho mximo da alocao noSGBD (rea chamada de PGA). Se o desenvolvedor violar o tamanhomximo o SGBD ir lanar uma exceo

    Prof. Arquimedes Lima 76

  • 5/20/2018 02_-_PLSQL (1)

    77/164

    Exemplo NESTED TABLEDECLARE

    TYPEnumber_table IS TABLE OF NUMBER;

    listNUMBER_TABLE:= number_table(1,2,3,4,5,6,7,8);

    BEGIN

    list.DELETE(2);

    FORi IN1..list.COUNT+1LOOPIFlist.EXISTS(i) THEN

    dbms_output.put('['||list(i)||']');

    END IF;

    END LOOP;

    dbms_output.new_line;

    dbms_output.put_line( 'N elementos:'||list.COUNT );

    END;

    Prof. Arquimedes Lima 77

    E l NESTED TABLE

  • 5/20/2018 02_-_PLSQL (1)

    78/164

    Exemplo NESTED TABLEDECLARE

    TYPEnumber_table IS TABLEOF NUMBER;

    list NUMBER_TABLE;

    procedureincluir( p_valor number)

    is

    idxpls_integer;begin

    idx := list.COUNT + 1;

    list.extend(1);

    list(idx) := p_valor;

    end;

    BEGIN

    /* Inicializando a lista */

    list := number_table();

    incluir( 10 ); incluir( 20 );

    incluir( 30 ); incluir( 40 );

    list.DELETE(3);

    FORi IN1..list.COUNT+1 LOOP

    IFlist.EXISTS(i) THEN

    dbms_output.put('['||list(i)||']');

    END IF;

    END LOOP;

    dbms_output.new_line;

    dbms_output.put_line( 'N

    elementos:'||list.COUNT);

    END;

    Prof. Arquimedes Lima 78

  • 5/20/2018 02_-_PLSQL (1)

    79/164

    Vetores associativos (ARRAY)

    Tambm chamado deAssociative Array

    Pode ser utilizados com indexadores numricos e strings

    Tambm traz a idia que no preciso estabelecer a princpio aquantidade de elementos que ser utilizada

    Neste tipo de coleo preciso especificar a natureza do indexador

    Prof. Arquimedes Lima 79

  • 5/20/2018 02_-_PLSQL (1)

    80/164

    Exemplo ARRAYDECLARE

    TYPEnumber_table IS TABLE OF NUMBER

    INDEX BY PLS_INTEGER;

    listNUMBER_TABLE;

    BEGIN

    FORi IN1..6 LOOP

    list(i) := i;END LOOP;

    list.DELETE(2);

    FORi IN1..list.COUNT+1 LOOP

    IFlist.EXISTS(i) THEN

    dbms_output.put('['||list(i)||']');

    END IF;END LOOP;

    dbms_output.new_line;

    END;

    Prof. Arquimedes Lima 80

  • 5/20/2018 02_-_PLSQL (1)

    81/164

    Exemplo ARRAY

    set serveroutput on;

    declare

    typetTab is table ofvarchar2(40)

    index by varchar(2);

    tab tTab;begin

    tab( 'SE' ) := 'Nordeste';

    tab( 'AM' ) := 'Norte';

    tab( 'PR' ) := 'Sul';

    dbms_output.put_line( 'Sergipe.: ' || tab( 'SE') );dbms_output.put_line( 'Amazonas: ' || tab( 'AM') );

    dbms_output.put_line( 'Paran..: ' || tab( 'PR') );

    end;

    Prof. Arquimedes Lima 81

    Exemplo ARRAY

  • 5/20/2018 02_-_PLSQL (1)

    82/164

    Exemplo ARRAYDECLARE

    typetTab is table of varchar2(40)index by varchar2(2);

    tab tTab;

    key varchar2(2);

    BEGIN

    tab( 'SE' ) := 'Nordeste';

    tab( 'AM' ) := 'Norte';

    tab( 'PR' ) := 'Sul';

    key := tab.first;

    whilekey is not null loop

    dbms_output.put_line( 'Estado.: '||key||' ->

    '||'Regio: ' ||tab( key ) );

    key := tab.next( key );

    end loop;

    END; Prof. Arquimedes Lima 82

  • 5/20/2018 02_-_PLSQL (1)

    83/164

    Exemplo ARRAYDECLARE

    typetTab is table ofcursos%rowtype

    index bypls_integer;

    tab tTab;

    BEGIN

    tab(1).cod_curso := 1; tab(2).cod_curso := 2;tab(1).nom_curso := 'CC'; tab(2).nom_curso := 'SI';

    dbms_output.put_line( 'Curso-1: '||tab( 1 ).cod_curso ||

    ' - ' ||

    tab( 1 ).nom_curso );

    dbms_output.put_line( 'Curso-2: '||tab( 2 ).cod_curso ||

    ' - ' ||

    tab( 2 ).nom_curso );

    END;

    Prof. Arquimedes Lima 83

    E l ARRAY

  • 5/20/2018 02_-_PLSQL (1)

    84/164

    Exemplo ARRAY

    DECLARE

    TYPEt_pessoa IS RECORD

    ( id number(5),

    cpf char(11),

    nome varchar2(60) );

    type tTab is table of t_pessoaindex bypls_integer;

    tab tTab;

    BEGIN

    tab(1).id := 1;

    tab(1).cpf := '45836214578';

    tab(1).nome := 'Maria';

    ...

    tab(2).id := 2;

    tab(2).cpf := '96325412358';

    tab(2).nome := 'Rosa';

    fori in 1 .. tab.COUNTloopdbms_output.put_line(

    tab(i).id||'-'||

    tab(i).cpf||'-'||

    tab(i).nome );

    end loop;

    END;

    Prof. Arquimedes Lima 84

  • 5/20/2018 02_-_PLSQL (1)

    85/164

    Excees

    Mecanismo utilizado na linguagem para reportar advertncias ou errosde programas em tempo de execuo;

    Existem duas modalidades de excees: Excees do sistema ou

    excees definidas pelo usurio;

    Quando uma exceo ocorre o fluxo normal do programa interrompido e o controle transferido para o bloco de tratamento deexcees;

    As excees geradas devem ser tratadas com o uso de sentenasWHENna clusula EXCEPTION

    Prof. Arquimedes Lima 85

  • 5/20/2018 02_-_PLSQL (1)

    86/164

    Excees

    Sintaxe bsica:WHEN THEN

    Em uma clusula EXCEPTIONpodem ser

    definidas vrias clusulas WHEN;

    A palavra reservada OTHERSpode ser utilizada para iniciar otratamento de qualquer exceo gerada;

    As vrias excees tratadas so analisadas na clusula EXCEPTIONna ordem em que so definidas na sentena WHEN;

    Prof. Arquimedes Lima 86

  • 5/20/2018 02_-_PLSQL (1)

    87/164

    Excees

    No tratamento de excees com a sentena WHENapenas oscomandos de uma nica sentena so executados (exclusivo);

    Os erros so propagados entre os blocos PL/SQLde acordo com a

    hierarquia de chamada dos blocos;

    Se a exceo no for tratada na hierarquia de blocos a mensagem deerro ser exibida para o usurio na forma de um erro Oracle;

    Os erros so caracterizados por um cdigo e uma mensagem quepodem ser capturados atravs das funes implcitas SQLCODEeSQLERRM;

    Prof. Arquimedes Lima 87

    Exemplo Exceo

  • 5/20/2018 02_-_PLSQL (1)

    88/164

    Exemplo ExceoDECLARE

    aNUMBER

    ;

    BEGIN

    DECLARE

    bVARCHAR2(2);

    BEGIN

    SELECT1 INTOb

    FROMdual

    WHERE1 = 2;

    a := b;

    EXCEPTION

    WHEN VALUE_ERROR THEN

    dbms_output.put_line('Voc no pode colocar ['||b||

    '] numa string de um caracter');

    END;EXCEPTION

    WHEN OTHERS THEN

    dbms_output.put_line('Exceo geral ['||SQLERRM||'].');

    END;

    Prof. Arquimedes Lima 88

    Exemplo Exceo

  • 5/20/2018 02_-_PLSQL (1)

    89/164

    p DECLARE

    aNUMBER;

    e EXCEPTION;BEGIN

    DECLARE

    bVARCHAR2(2) := 'AB';

    BEGIN

    RAISEe;

    EXCEPTION

    WHEN others THEN

    a := b; -- Ocorre uma exceo

    dbms_output.put_line('Este comando no ser

    executado.');

    END;EXCEPTION

    WHENothersTHEN

    dbms_output.put_line('Captura da exceo

    ['||SQLCODE||'].');

    END; Prof. Arquimedes Lima 89

  • 5/20/2018 02_-_PLSQL (1)

    90/164

    Outro exemplo ...

    DECLARE

    a varchar2(1) := :valor;

    BEGIN

    dbms_output.put_line('Esta linha no ser impressa

    ['||a||']');

    EXCEPTION

    WHEN others THEN

    dbms_output.put_line('Exceo ['|| sqlcode||']:

    '||sqlerrm);

    END;

    Prof. Arquimedes Lima 90

  • 5/20/2018 02_-_PLSQL (1)

    91/164

    Excees Pr-Definidas (comuns)

    DUP_VAL_ON_INDEX

    ORA-00001 (SQLCODE = -1)

    retornado quando ocorre violao de chave primria ou chavenica;

    NO_DATA_FOUND

    ORA-01403 (SQLCODE = -100)

    lanada quando um comando SELECT INTO, por exemplodeveria recuperar um elemento e no recupera;

    TOO_MANY_ROWS

    ORA-01422 (SQLCODE = -1422) gerada quando um comando SELECT INTO em um bloco

    PL/SQL recupera mais de uma linha no resultado

    Prof. Arquimedes Lima 91

    Excees Pr-Definidas (comuns)

  • 5/20/2018 02_-_PLSQL (1)

    92/164

    Excees Pr-Definidas (comuns)

    INVALID_NUMBER

    ORA-01722 (SQLCODE = -1722) Lanada quando uma converso para um valor numrico

    invlida;

    VALUE_ERROR

    ORA-06502 (SQLCODE = -6502)

    Esta associada a operaes aritmticas de converso, atribuio avariveis de tamanho menor e truncamento;

    ZERO_DIVIDE

    ORA-01476 (SQLCODE = -1476)

    Erro de diviso por zero

    SUBSCRIPT_BEYOND_COUNT

    ORA-06533 (SQLCODE = -6533)

    Acesso a uma posio no alocada de uma NESTED TABLE ouVARRAY

    Prof. Arquimedes Lima 92

  • 5/20/2018 02_-_PLSQL (1)

    93/164

    Excees Definidas pelo Usurio

    Os usurios podem lanar suas prprias excees dentro de um blocoPL/SQL

    O lanamento possvel atravs do comando

    RAISE_APPLICATION_ERROR

    Sintaxe:raise_application_error( ,

  • 5/20/2018 02_-_PLSQL (1)

    94/164

    Excees

    As excees so utilizadas para validao dos dados conforme regrasde negcio

    Essas mensagens so implementadas em gatilhos, funes, rotinas

    armazenadas e pacotes;

    Uma exceo pode ser relanada em uma seo de tratamentoatravs do comando RAISE;

    Prof. Arquimedes Lima 94

    Packages

  • 5/20/2018 02_-_PLSQL (1)

    95/164

    Packages

    So as bibliotecas armazenadas no banco de dados

    Podemos afirmar que representa o backboneno desenvolvimento deaplicaes em bancos de dados Oracle

    Os pacote viabilizam agrupar funes e procedimentos em bibliotecas

    Dentro dos pacotes possvel implementar variveis compartilhadas,tipos de dados e componentes que so as funes e procedimentos

    Os pacotes so definidos em duas partes distintas:

    Especificao (interface): Publica a declarao; Corpo (implementao): Implementa cada item da especificao;

    Prof. Arquimedes Lima 95

    Packages

  • 5/20/2018 02_-_PLSQL (1)

    96/164

    Packages

    possvel criar uma funo / procedimento no corpo do pacote e nodeclar-las na especificao, neste caso podemos afirmar que soprivadas

    Um pacote de propriedade do esquema que foi compilada

    Caso seja necessrio utilizar em outros esquema ser necessrio oprivilgio de EXECUTE

    Os pacotes podem ser executados atravs de blocos annimos,

    procedimentos armazenados, funes, gatilhos e atravs das funesem sentenas SQL

    Prof. Arquimedes Lima 96

  • 5/20/2018 02_-_PLSQL (1)

    97/164

    Packages

    A visibilidade e referncia das rotinas, tipos e variveis ocorre daseguinte forma:

    Aquelas que so definidas na especificao so visveis de

    qualquer ponto do pacote

    Enquanto as que so definidas na implementao so visveis pararotinas implementadas a partir de sua definio

    Prof. Arquimedes Lima 97

  • 5/20/2018 02_-_PLSQL (1)

    98/164

    Packages

    Sintaxe Especificao

    CREATEORREPLACE PACKAGE IS

    /* Declarao de tipos e variveis pblicos */

    /* Assinaturas das funes / procedimentos */

    END;

    Sintaxe Corpo

    CREATE OR REPLACE PACKAGE BODY IS

    /* Declarao de tipos e variveis privados */

    /* Implementao de funes / procedimentos privados */

    Prof. Arquimedes Lima 98

  • 5/20/2018 02_-_PLSQL (1)

    99/164

    ConsideraesPackages

    Uma especificao de pacote pode existir sem um corpo de pacote,mas um corpo no pode existir sem uma especificao de pacote

    A sintaxe para definio das PROCEDURESe FUNCTIONSno corpo dopacote deve apenas retirar a clusula CREATE OR REPLACE Segueo mesma forma de definio em blocos annimos

    Para a especificao (interface), a declarao possui apenas aassinatura da rotina

    Prof. Arquimedes Lima 99

  • 5/20/2018 02_-_PLSQL (1)

    100/164

    Exemplo Especificao

    create or replace packagepkg_bibl is

    /* Tipo registro pblico */

    typet_reg_cont is record( data date,

    tot number(3) );

    /* Funo que obtm a idade a partir de uma data

    de nascimento */

    functionidade( p_dat_nasc date) returnnumber;

    end;

    Prof. Arquimedes Lima 100

    l

  • 5/20/2018 02_-_PLSQL (1)

    101/164

    Exemplo Corpo

    create or replace package bodypkg_bibl is

    ---------------------------------------------------

    /* Varivel privada do corpo da package */

    v_reg_cont t_reg_cont;

    ---------------------------------------------------

    functionidade( p_dat_nasc date) return number

    is begin

    return trunc(months_between( sysdate,

    p_dat_nasc ) / 12 );end;

    end;

    Prof. Arquimedes Lima 101

    l i i li

  • 5/20/2018 02_-_PLSQL (1)

    102/164

    Exemplo Inicializaocreate or replace package bodypkg_bibl is

    ---------------------------------------------------

    /* Varivel privada do corpo da package */

    v_reg_cont t_reg_cont;

    ---------------------------------------------------functionidade( p_dat_nasc date) return number

    is begin

    returntrunc(months_between( sysdate,

    p_dat_nasc ) / 12 );

    end;

    begin

    v_reg_cont.data := sysdate; v_reg_cont.tot := 0;

    end;Prof. Arquimedes Lima 102

    U ili Bl A i

  • 5/20/2018 02_-_PLSQL (1)

    103/164

    Utilizao Bloco Annimo

    set serveroutput on;

    declare

    v_reg pkg_bibl.t_reg_cont;

    begin

    v_reg.data := sysdate;

    v_reg.tot := 0;

    dbms_output.put_line( pkg_bibl.idade(

    to_date( '27/04/1976','DD/MM/YYYY') ) );

    end;

    Prof. Arquimedes Lima 103

    U ili SQL

  • 5/20/2018 02_-_PLSQL (1)

    104/164

    Utilizao em SQLselectnom_alu asNome,

    dat_nasc asNascimento,

    pkg_bibl.idade( dat_nasc ) Idade

    fromacademico.alunos

    whererownum

  • 5/20/2018 02_-_PLSQL (1)

    105/164

    Utilizao em Funescreate or replace

    functionf_obter_idade( p_dat_nasc date) return number

    is begin

    ifp_dat_nasc is null then

    raise_application_error( -20000, 'A data de nascimento '||

    'deve ser informada');

    else

    returnpkg_bibl.idade( p_dat_nasc );

    end if;

    end;

    selectnom_alu, dat_nasc,f_obter_idade( dat_nasc ) idade

    fromacademico.alunos

    whererownum

  • 5/20/2018 02_-_PLSQL (1)

    106/164

    create or replace packagepkg_bibl is

    /* Funo que obtm a idade em relao a uma data

    especfica passada como parmetro */

    functionidade( p_dat_nasc date,

    p_dat_ref datedefault sysdate)

    return number;

    end;

    create or replace package bodypkg_bibl is

    function idade( p_dat_nasc date,

    p_dat_ref datedefault sysdate)return number

    is begin

    return trunc(months_between( p_dat_ref,

    p_dat_nasc ) / 12 );

    end;

    end; Prof. Arquimedes Lima 106

    S b d C

  • 5/20/2018 02_-_PLSQL (1)

    107/164

    Sobrecarga de Componentes

    Permite que o desenvolvedor utilize o mesmo nome para diferentesrotinas dentro de um pacote

    Requer que os parmetros formais das rotinas difiram em nmero

    ordem ou famlia de tipos

    Permite que haja mais flexibilidade

    Somente rotinas locais ou empacotadas podem ser sobrecarregadas

    Prof. Arquimedes Lima 107

    S b d C t

  • 5/20/2018 02_-_PLSQL (1)

    108/164

    Sobrecarga de Componentes

    create or replace packagepkg_bibl is

    /* Funo que obtm a idade tomando com base

    a data atual */

    functionidade( p_dat_nasc date) return number;

    /* Funo que obtm a idade em relao a uma data

    especfica passada como parmetro */

    functionidade( p_dat_nasc date,

    p_dat_ref date) return number;

    end;

    Prof. Arquimedes Lima 108

    S b d C t

  • 5/20/2018 02_-_PLSQL (1)

    109/164

    Sobrecarga de Componentescreate or replace package bodypkg_bibl is---------------------------------------------------

    functionidade( p_dat_nasc date,

    p_dat_ref date) return number

    is begin

    returntrunc(months_between( p_dat_ref,p_dat_nasc ) / 12 );

    end;

    ---------------------------------------------------

    functionidade( p_dat_nasc date ) return number

    is beginreturnidade( p_dat_nasc, sysdate );

    end;

    end;

    Prof. Arquimedes Lima 109

    E i

  • 5/20/2018 02_-_PLSQL (1)

    110/164

    Exerccios

    Crie uma package (pkg_bibgeral) contendo osprocedimento e funes criados nos exercciosanteriores. (questo 11 da lista de exerccios)

    Prof. Arquimedes Lima 110

    P k S

  • 5/20/2018 02_-_PLSQL (1)

    111/164

    Packagese Sesses

    O estado (variveis) definidos em umapackageso persistentesdurante a sesso do usurio

    O cdigo dapackage compartilhado entre as sesses, mas o estado

    no

    Sobre as sesses podemos afirmar que:

    O estado de uma varivel de pacote persiste ao longo dastransaes de uma sesso

    O estado no persiste de uma sesso para outra de um mesmousurio

    O estado no persiste de um usurio para outro;

    Prof. Arquimedes Lima 111

    P k S

  • 5/20/2018 02_-_PLSQL (1)

    112/164

    Packagese Sesses

    A persistncia dos dados durante a sesso pode ser utilizada comomecanismo para implementao de recursos avanados de seguranae BD ativos

    Os pacotes permitem a definio de rotinas e dados, sendo que area de memria utilizada pelaspackagesno compartilhada entresesses diferentes

    Cada sesso tem uma rea privada para os dados de umapackage,mesmo que o seu cdigo esteja compartilhado

    Prof. Arquimedes Lima 112

    E l U d S

  • 5/20/2018 02_-_PLSQL (1)

    113/164

    Exemplo Uso de Sesso

    /* Especificao do PACOTE */

    create or replace packagepkg_teste

    is

    functionobter_nome return varchar2;

    proceduresetar_nome( p_valor varchar2);

    end;

    Prof. Arquimedes Lima 113

    Exemplo Uso de Sesso

  • 5/20/2018 02_-_PLSQL (1)

    114/164

    Exemplo Uso de Sesso/* Corpo do pacote */

    create or replace package bodypkg_teste

    is

    v_nome varchar2(30);

    proceduresetar_nome( p_valor varchar2)

    is begin

    v_nome := p_valor;

    end;

    functionobter_nome return varchar2

    is begin

    returnv_nome;

    end;

    end;Prof. Arquimedes Lima 114

    E l U d S

  • 5/20/2018 02_-_PLSQL (1)

    115/164

    Exemplo Uso de Sesso Sesso 01

    begin

    pkg_teste.setar_nome( 'Teste sesso 01');

    end;

    selectpkg_teste.obter_nome from dual;

    Sesso 02

    begin

    pkg_teste.setar_nome( 'Teste sesso 02');

    end;

    selectpkg_teste.obter_nome from dual;

    Prof. Arquimedes Lima 115

  • 5/20/2018 02_-_PLSQL (1)

    116/164

    Exemplo PRODUTOS_PKG

    Prof. Arquimedes Lima 116

    Removendo uma Package

  • 5/20/2018 02_-_PLSQL (1)

    117/164

    Removendo umaPackage

    Utilize o comando DROPPACKAGE

    Sintaxe:DROP PACKAGE[BODY] ;

    Se a clusula BODYfor especificada, apenas o corpo excludo

    Exemplos

    DROP PACKAGEPKG_BIBL;

    DROP PACKAGE BODYPKG_BIBL;

    Prof. Arquimedes Lima 117

    Vantagens das Packages

  • 5/20/2018 02_-_PLSQL (1)

    118/164

    Vantagens dasPackages

    Modularidade

    Projeto de aplicaes mais simples de codificar

    Informaes ocultas, ou seja, construes relacionadas aencapsulamento

    As construes privadas esto ocultas e inacessveis

    Toda a codificao est escondida no corpo

    Prof. Arquimedes Lima 118

    Vantagens das Packages

  • 5/20/2018 02_-_PLSQL (1)

    119/164

    Vantagens dasPackages

    Funcionalidade ampliada: persistncia de variveis e cursores

    Melhor desempenho:

    O pacote inteiro carregado na memria quando feita a primeirareferncia

    Somente uma cpia do cdigo na memria para todos os usurios

    Sobrecarga de componentes

    Prof. Arquimedes Lima 119

    Gatilhos (Triggers)

  • 5/20/2018 02_-_PLSQL (1)

    120/164

    Gatilhos (Triggers)

    Bloco nomeado orientado a eventos;

    Diferentemente dos pacotes, funes e procedimento

    armazenados no podem ser chamados diretamente;

    Sob determinada evento e condio algumas aespodem ser tomadas:

    Lanamento de uma exceo abortando a operaode acordo com a situao;

    Realizar outras opes relacionadas a manuteno dabase de dados;

    Prof. Arquimedes Lima 120

    Tipos de Gatilhos

  • 5/20/2018 02_-_PLSQL (1)

    121/164

    Tipos de Gatilhos

    Prof. Arquimedes Lima 121

    BEFORE

    EXEC.D

    ML

    AFTER

    ST TEMENT

    (Sentena)

    STATEMENT

    (Sentena)ROW

    (Linha)

    ROW

    (Linha)

    1 2 3 4 5

    Sintaxe Bsica Trigger

  • 5/20/2018 02_-_PLSQL (1)

    122/164

    Sintaxe Bsica Trigger

    CREATE[OR REPLACE] TRIGGER{BEFORE|AFTER}

    ON

    [FOR EACH ROW]

    ::= ( OR )*

    ::= INSERT| DELETE|UPDATE[ OF ]

    Prof. Arquimedes Lima 122

    Clusula BEFORE e AFTER

  • 5/20/2018 02_-_PLSQL (1)

    123/164

    Clusula BEFOREe AFTER

    Definem o momento da execuo do gatilho em relao aoperao DMLque a disparou;

    Antes da execuo da operao DML(BEFORE), asrestries declarativas e modificaes ainda no foramefetuados;

    As informaes tratadas nos gatilhos de AFTERtm uma

    melhor garantia j foram submetidas as restriesdeclarativas;

    Prof. Arquimedes Lima 123

    Definies

  • 5/20/2018 02_-_PLSQL (1)

    124/164

    Definies

    Podemos definir que uma sentena um comando SQLsubmetido ao SGBD;

    Uma nica sentena pode modificar uma ou vrias linhasda tabela;

    Exemplo:

    INSERT INTOALUNOS

    SELECT* FROMALUNOS_BKP;

    Prof. Arquimedes Lima 124

    Clusula FOR EACH ROW

  • 5/20/2018 02_-_PLSQL (1)

    125/164

    Clusula FOR EACH ROW

    Caso seja definida para a trigger indica que sua execuoacontecer uma vez para cada linha modificada pelasentena, ou seja, uma trigger de linha(ROW);

    A omisso desta clusula indica que o gatilho (trigger) de sentena (STATEMENT), sendo executada uma nicavez para cada comando SQLque acione o evento da

    trigger;

    Prof. Arquimedes Lima 125

    Pseudo Registros OLD/NEW

  • 5/20/2018 02_-_PLSQL (1)

    126/164

    Pseudo Registros OLD/NEW

    Nos gatilhos de linha possvel obter os valores da linhamantida pela operao atravs dos registros implcitosOLDeNEW;

    Sua utilizao semelhante a construo %ROWTYPE;

    O registro OLDpossui os valores anteriores a mudana eso visveis somente nas operaes de DELETEeUPDATE;

    Exemplos: :new.mat_alu

    :old.status

    Prof. Arquimedes Lima 126

    Pseudo Registros OLD/NEW

  • 5/20/2018 02_-_PLSQL (1)

    127/164

    Pseudo Registros OLD/NEW

    ONEWpossui os valores novos provenientes dasoperaes de INSERTe UPDATE;

    Os dados do registroNEWs podem ser alterados nastriggers de BEFORE ROW;

    Os registos OLDjamais podem ser modificados;

    Prof. Arquimedes Lima 127

    Tipos de Gatilhos

  • 5/20/2018 02_-_PLSQL (1)

    128/164

    Tipos de Gatilhos

    Prof. Arquimedes Lima 128

    BEFORE

    EXEC.D

    ML

    AFTER

    STATEMENT

    (Sentena)

    STATEMENT

    (Sentena)

    ROW

    (Linha)

    ROW

    (Linha)

    1 2 3 4 5

    Executadauma nicavez;

    Executadauma nicavez;

    Executada p/cada linhaafetada;

    Pode acessarOLD e NEW;

    Permitemodificar o

    NEW;

    Executada p/cada linhaafetada;

    Acessa OLDe NEW;

    No modificaNEW;

    Exemplo BEFORE Statement

  • 5/20/2018 02_-_PLSQL (1)

    129/164

    Exemplo BEFORE Statement

    CREATE OR REPLACE TRIGGERPRODUTOS_BIUDS

    BEFORE DELETE OR INSERT OR UPDATE

    ONPRODUTOS

    begin

    dbms_output.put_line( '1. PRODUTOS_BIUDS');

    end;

    /

    Prof. Arquimedes Lima 129

    Exemplo BEFORE ROW

  • 5/20/2018 02_-_PLSQL (1)

    130/164

    Exemplo BEFORE ROW

    CREATE OR REPLACE TRIGGERPRODUTOS_BIUD

    BEFORE DELETE OR INSERT OR UPDATE

    ONPRODUTOS

    FOR EACH ROWbegin

    dbms_output.put_line( '2. PRODUTOS_BIUD');

    end;

    /

    Prof. Arquimedes Lima 130

    Exemplo AFTER ROW

  • 5/20/2018 02_-_PLSQL (1)

    131/164

    Exemplo AFTER ROW

    CREATE OR REPLACE TRIGGERPRODUTOS_AIUD

    AFTER DELETE OR INSERT OR UPDATE

    ONPRODUTOS

    FOR EACH ROW

    begin

    dbms_output.put_line( '3. PRODUTOS_AIUD');

    end;

    /

    Prof. Arquimedes Lima 131

    Exemplo AFTER STATEMENT

  • 5/20/2018 02_-_PLSQL (1)

    132/164

    Exemplo AFTER STATEMENT

    CREATE OR REPLACE TRIGGERPRODUTOS_AIUDS

    AFTER DELETE OR INSERT OR UPDATE

    ONPRODUTOS

    DECLARE

    begin

    dbms_output.put_line( '4. PRODUTOS_AIUDS' );

    end;

    /

    Prof. Arquimedes Lima 132

    Sequncia dos Eventos

  • 5/20/2018 02_-_PLSQL (1)

    133/164

    Sequncia dos Eventos

    SQL> insert intoprodutos

    values( 1, 'P1', 'A', null);

    1 row inserted

    1. PRODUTOS_BIUDS -> Before Statement Trigger

    2. PRODUTOS_BIUD -> Before Row Trigger

    3. PRODUTOS_AIUD -> After Row Trigger

    4. PRODUTOS_AIUDS -> After Statement Trigger

    Prof. Arquimedes Lima 133

    Eventos x Operaes em Massa

  • 5/20/2018 02_-_PLSQL (1)

    134/164

    Eventos x Operaes em Massa

    SQL> selectcount(*)fromprodutos_temp;

    COUNT(*)

    ----------

    4

    SQL> insert intoprodutos

    select* fromprodutos_temp;

    4 rows inserted

    Prof. Arquimedes Lima 134

    Eventos x Operaes em Massa

  • 5/20/2018 02_-_PLSQL (1)

    135/164

    Eventos x Operaes em Massa

    Prof. Arquimedes Lima 135

    SQL> insert intoprodutos

    select* fromprodutos_temp;

    4 rows inserted1. PRODUTOS_BIUDS

    2. PRODUTOS_BIUD

    3. PRODUTOS_AIUD

    2. PRODUTOS_BIUD

    3. PRODUTOS_AIUD

    2. PRODUTOS_BIUD

    3. PRODUTOS_AIUD

    2. PRODUTOS_BIUD

    3. PRODUTOS_AIUD4. PRODUTOS_AIUDS

    Before Statement

    After Statement

    After RowBefore Row

    Variveis Implcitas

  • 5/20/2018 02_-_PLSQL (1)

    136/164

    Variveis Implcitas

    So variveis booleadasque podem ser utilizadas nocorpo do gatilho e indica qual o evento que estocorrendo no banco de dados:

    INSERTING: Evento de incluso;

    UPDATING: Evento de atualizao;

    DELETING: Evento de excluso;

    Prof. Arquimedes Lima 136

    Trigger Before Statement

  • 5/20/2018 02_-_PLSQL (1)

    137/164

    TriggerBefore Statement

    CREATE OR REPLACE TRIGGERPRODUTOS_BIUDS

    BEFORE DELETE OR INSERT OR UPDATE

    ONPRODUTOS

    declare

    v_totpls_integer;

    begin

    selectcount(*) intov_tot

    fromprodutos;

    dbms_output.put_line( 'Total prod. antes sentena: '||v_tot );

    end;

    /

    Prof. Arquimedes Lima 137

    Trigger Before Row

  • 5/20/2018 02_-_PLSQL (1)

    138/164

    TriggerBefore RowCREATE OR REPLACE TRIGGERPRODUTOS_BIUD

    BEFORE DELETE OR INSERT OR UPDATE

    ONPRODUTOS

    FOR EACH ROW

    begin

    if inserting then

    if:new.status is NULLthen

    :new.status := 'A';

    end if;

    selectseq_produto.nextval into :new.codigo

    fromdual;end if;

    end;

    /

    Prof. Arquimedes Lima 138

    Trigger After Row

  • 5/20/2018 02_-_PLSQL (1)

    139/164

    TriggerAfter Row

    CREATE OR REPLACE TRIGGERPRODUTOS_AIUD

    AFTER DELETE OR INSERT OR UPDATE

    ONPRODUTOS

    FOR EACH ROW

    begin

    if updating and :old.status:new.status thenraise_application_error( -20000, Alterao de status:

    ||:old.status||;||

    :new.status );

    end if;

    end;

    /

    Prof. Arquimedes Lima 139

    Trigger After Stament

  • 5/20/2018 02_-_PLSQL (1)

    140/164

    TriggerAfter Stament

    Prof. Arquimedes Lima 140

    CREATE OR REPLACE TRIGGERPRODUTOS_AIUDS

    AFTER DELETE OR INSERT OR UPDATE

    ONPRODUTOS

    declare

    v_totpls_integer;

    begin

    selectcount(*) intov_tot

    fromprodutos;

    dbms_output.put_line( 'Total prod. aps sentena: '||v_tot );

    end;

    /

    Estado dos Dados - Triggers

  • 5/20/2018 02_-_PLSQL (1)

    141/164

    Estado dos Dados Triggers

    Os comandos SELECTexecutados em uma triggerBEFORE STATEMENTenxergam o banco de dados semnenhuma das modificaes geradas pela sentena;

    Nos gatilhos de AFTER STATEMENT, os comandosSELECTj realizam a leitura com as modificaes,mesmo que estas sejam abortadas por uma exceoposteriormente;

    Para as triggers de linha, no permitido executar umaconsulta sob os dados da tabela para qual a trigger definida;

    Prof. Arquimedes Lima 141

    Estado dos Dados - Triggers

  • 5/20/2018 02_-_PLSQL (1)

    142/164

    Estado dos Dados Triggers

    Se um comando SELECTfor realizado no gatilho de linha,ou em qualquer rotina chamada por ela diretamente ouindiretamente, gerada uma exceo chamada deMUTATING TABLE;

    A exceo para regra a trigger de BEFORE INSERT delinha, cuja seleo no visualiza as modificaes na

    base de dados;

    Prof. Arquimedes Lima 142

    Tipos de Gatilhos

  • 5/20/2018 02_-_PLSQL (1)

    143/164

    Tipos de Gatilhos

    Prof. Arquimedes Lima 143

    BEFORE

    EXEC.D

    ML

    AFTER

    STATEMENT STATEMENTROW ROW

    1 2 3 4 5

    Executadauma nicavez;

    Visualiza oBD semalterao

    Executada

    uma nicavez;

    Visualiza oBD jalterado

    Executada p/cada linhaafetada;

    Pode acessarOLD e NEW;

    Permitemodificar oNEW;

    No permiteSELECT natab. Base

    Before insertpermiteSELECT

    Executada p/cada linhaafetada;

    Acessa OLDe NEW;

    No modificaNEW;

    No admiteSELECT na

    tabela base

    Exemplo de Tabela Mutante

  • 5/20/2018 02_-_PLSQL (1)

    144/164

    Exemplo de Tabela Mutante

    Prof. Arquimedes Lima 144

    CREATE TABLEmutante

    ( mutant_id NUMBER

    , mutant_name VARCHAR2(20));

    -- Incluso das "tartarugas ninjas"

    INSERT INTO mutante VALUES (1,'Donatello');

    INSERT INTO mutante VALUES (2,'Leonardo');

    INSERT INTO mutante VALUES (3,'Michelangelo');

    INSERT INTO mutante VALUES (4,'Raphael');

    Exemplo Tabela Mutante

  • 5/20/2018 02_-_PLSQL (1)

    145/164

    e p o abe a uta te

    CREATE OR REPLACE TRIGGERmutante_ad

    AFTER DELETE ONmutante

    FOR EACH ROW

    DECLARE

    v_totNUMBER;

    BEGIN

    SELECTCOUNT(*)INTOv_tot

    FROMmutante;

    dbms_output.put_line('Total mutantes:['||v_tot||']');END;

    /

    Prof. Arquimedes Lima 145

    Exemplo Tabela Mutante

  • 5/20/2018 02_-_PLSQL (1)

    146/164

    p

    SQL> deletefrom mutantewheremutant_id = 3;

    delete from mutante where mutant_id = 3

    ORA-04091: a tabela SYSTEM.MUTANTE mutante;

    talvez o gatilho/funo no possa localiz-la

    ORA-06512: em "SYSTEM.MUTANTE_AD", line 4

    ORA-04088: erro durante a execuo do gatilho

    'SYSTEM.MUTANTE_AD'

    Prof. Arquimedes Lima 146

    Estudo de Caso Exemplo

  • 5/20/2018 02_-_PLSQL (1)

    147/164

    Verifique a tabela de cursos:

    SQL> desc academico.cursos;

    Name Type Nullable Default Comments

    --------- ------------ -------- ------- --------

    COD_CURSO NUMBER(3)NOM_CURSO VARCHAR2(40)

    TOT_CRED NUMBER(3)

    IDT_PROF NUMBER(6) Y

    Elabore um gatilho que implemente a seguinte regra: Um

    professor s pode coordenar no mximo dois cursos;

    Prof. Arquimedes Lima 147

    Estudo de Caso Exemplo

  • 5/20/2018 02_-_PLSQL (1)

    148/164

    p

    Essa validao pode ser implementada na trigger delinha?

    Nas triggers de linha possvel saber, atravs dasvariveis OLDe NEW, as linhas que esto sendo

    modificadas, mas no podemos acessar a tabela emmutao;

    Na trigger de sentena, possvel acessar a tabela, mas

    no so conhecidas as linhas que sofreram modificao;

    Como solucionar?

    Prof. Arquimedes Lima 148

    Estudo de Caso ExemploSoluo: Utilizar um vetor em memria em que a trigger

  • 5/20/2018 02_-_PLSQL (1)

    149/164

    Soluo: Utilizar um vetor em memria em que a triggerde linha informe a trigger de sentena quais os dados que

    devem ser validados;

    Prof. Arquimedes Lima149

    BEFORE AFTER

    STATEMENT(Sentena)

    STATEMENT(Sentena)

    ROW(Linha)

    ROW(Linha)

    1 2 3 4 5

    Iniciar vetor Obtm osdados dovetor

    Limpa o vetor

    Incluso dosdadosmodificadosno vetor

    Vetor

    S

    Q

    L

    Resoluo Estudo de Caso

  • 5/20/2018 02_-_PLSQL (1)

    150/164

    create or replace packageCURSOS_PKG is

    /* ======================================================= */

    functionobter_total_cursos( p_idt_prof number ) return number;

    /* ======================================================= */

    procedureiniciar_lista;

    /* ======================================================= */

    procedureadicionar_curso( p_cod_curso number,

    p_idt_prof number);

    /* ======================================================= */

    procedureobter_dados( p_pos number,

    p_cod_curso outnumber,

    p_idt_prof outnumber);

    /* ======================================================= */

    functionobter_total_itens return number;

    endCURSOS_PKG;

    Prof. Arquimedes Lima 150

    Resoluo Estudo de Casocreate or replace packagebodyCURSOS_PKG is

  • 5/20/2018 02_-_PLSQL (1)

    151/164

    TYPEt_reg_curso IS RECORD

    ( cod_curso cursos.cod_curso%type,idt_prof cursos.idt_prof%type );

    typet_lista_cursos

    is table oft_reg_curso index by pls_integer;

    v_lista_curso t_lista_cursos;

    /* ======================================================= */

    functionobter_total_cursos( p_idt_prof number) return number

    is

    v_totpls_integer;

    begin

    select count(*) intov_tot

    fromcursos

    whereidt_prof = p_idt_prof;

    returnv_tot;

    end;Prof. Arquimedes Lima 151

    Resoluo Estudo de Caso/* ======================================================= */

    function obter posicao( p cod c rso number

  • 5/20/2018 02_-_PLSQL (1)

    152/164

    functionobter_posicao( p_cod_curso number,

    p_idt_prof number) return binary_integer

    isv_pospls_integer:= -1;

    begin

    fori in1 .. v_lista_curso.count loop

    ifv_lista_curso(i).cod_curso = p_cod_curso and

    v_lista_curso(i).idt_prof = p_idt_prof then

    v_pos := i;

    exit;

    end if;

    end loop;

    returnv_pos;

    end;

    /* ======================================================= */

    procedureiniciar_lista

    is begin

    v_lista_curso.delete;

    end; Prof. Arquimedes Lima 152

    Resoluo Estudo de Caso

  • 5/20/2018 02_-_PLSQL (1)

    153/164

    /* ======================================================= */

    procedureadicionar_curso( p_cod_curso number,

    p_idt_prof number)

    is

    v_pospls_integer;

    begin

    v_pos := obter_posicao( p_cod_curso, p_idt_prof );

    ifv_pos = -1 then

    v_pos := v_lista_curso.COUNT+ 1;

    v_lista_curso( v_pos ).cod_curso := p_cod_curso;

    v_lista_curso( v_pos ).idt_prof := p_idt_prof;

    end if;

    end;

    Prof. Arquimedes Lima 153

    Resoluo Estudo de Caso/* ======================================================= */

  • 5/20/2018 02_-_PLSQL (1)

    154/164

    procedureobter_dados( p_pos number,

    p_cod_curso out number,

    p_idt_prof out number)

    is begin

    ifp_pos notbetween1 andv_lista_curso.count then

    p_cod_curso := null;

    p_idt_prof := null;

    else

    p_cod_curso := v_lista_curso( p_pos ).cod_curso;p_idt_prof := v_lista_curso( p_pos ).idt_prof;

    end if;

    end;

    /* ======================================================= */

    functionobter_total_itens return numberis begin

    returnv_lista_curso.count;

    end;

    endCURSOS_PKG; Prof. Arquimedes Lima 154

    Resoluo Estudo de Caso

  • 5/20/2018 02_-_PLSQL (1)

    155/164

    -- Before statement (insert, update)

    create or replace triggercursos_bius

    before insert or update

    onCURSOS

    begin

    /* Inicializa o vetor */

    cursos_pkg.iniciar_lista();

    end;

    Prof. Arquimedes Lima 155

    Resoluo Estudo de Caso

  • 5/20/2018 02_-_PLSQL (1)

    156/164

    -- After row (insert, update)create or replace triggercursos_aiu

    after insert or update

    onCURSOS

    for each row

    begin

    if( ( inserting) or( updating andnvl(:old.idt_prof,-1)

    nvl(:new.idt_prof,-1) ) ) and

    ( :new.idt_prof is not null) then

    /* Adio dos dados na sesso para validao das

    triggers de sentena */

    cursos_pkg.adicionar_curso( :new.cod_curso,

    :new.idt_prof );

    end if;

    end;

    Prof. Arquimedes Lima 156

    Resoluo Estudo de Casocreate or replace triggercursos_aius

    after insert or update onCURSOS

  • 5/20/2018 02_-_PLSQL (1)

    157/164

    declare

    v_cod_curso cursos.cod_curso%type;

    v_idt_prof cursos.idt_prof%type;begin

    forv_pos in1 .. cursos_pkg.obter_total_itens loop

    cursos_pkg.obter_dados( v_pos, v_cod_curso, v_idt_prof );

    if cursos_pkg.obter_total_cursos( v_idt_prof ) > 2 then

    raise_application_error( -20000, 'O coordenador j est '||

    'vinculado a quantidade '||

    'limite de cursos - '||

    'Curso: '||v_cod_curso );

    end if;

    end loop;

    /* Inicializa o vetor */

    cursos_pkg.iniciar_lista();

    exception

    when others then

    /* Inicializa o vetor */

    cursos_pkg.iniciar_lista();

    raise;

    end;

    Prof. Arquimedes Lima 157

    Comandos teis - Gatilhos

  • 5/20/2018 02_-_PLSQL (1)

    158/164

    RemoverDROP TRIGGER;

    DesabilitarALTER TRIGGER DISABLE;

    HabilitarALTER TRIGGER ENABLE;

    RecompilarALTER TRIGGER COMPILE;

    Consultar situao do gatilho e cdigo fonteUSER_TRIGGERSe USER_SOURCE

    Prof. Arquimedes Lima 158

    Gatilhos: Consideraes Finais

  • 5/20/2018 02_-_PLSQL (1)

    159/164

    A sentena SQL somente ser executada com sucessose todas as triggers e validaes envolvidas no geraremexcees;

    Caso seja realizada disparado uma sentena deatualizao na trigger de sentena, por exemplo, e logoem seguida for emitida uma exceo todas as operaesso desfeitas;

    Nos gatilhos no so permitidos: Commitse Rollbacks;

    Prof. Arquimedes Lima 159

    Triggers deInstead Of

  • 5/20/2018 02_-_PLSQL (1)

    160/164

    Possibilidade de realizar manuteno em vises; Devemos obedecer as seguintes regras:

    Na incluso todos os campos obrigatrios devem serprojetados;

    No permitido para sentenas SQLque utilizamDISTINCTou GROUP BY;

    Vises que fazem acesso a mais de uma tabela nopodem sofrer alteraes DML;

    Vises que possuam operadores de conjunto nopodem ser alteradas;

    No poder ser alterada para colunas calculadas;

    Prof. Arquimedes Lima 160

    Triggers deInstead Of

  • 5/20/2018 02_-_PLSQL (1)

    161/164

    No so gatilhos de INSERT, UPDATE ou DELETE;

    So gatilhos de INSTEAD OF;

    Permitem desenvolvimento de um gatilho com objetivo deescrever toda a lgica de manuteno de vises no

    atualizveis;

    Quando, por exemplo, um INSERT disparado em umaviso a lgica que insero dos dados

    Prof. Arquimedes Lima 161

    Triggers deInstead Of

  • 5/20/2018 02_-_PLSQL (1)

    162/164

    Uma trigger de Instead Ofpode ser considerada comoum gatilho de linha;

    Os valores OLDe NEWesto disponveis;

    Exemplo:

    createorreplaceviewv_pessoas as

    select'A'as"TIPO", mat_alu as"CODIGO", cod_curso,

    nom_alu as "NOME"

    fromalunos

    union

    select'P'as"TIPO", cod_prof as"CODIGO", cod_curso,

    nom_prof as"NOME"

    fromprofessores

    Prof. Arquimedes Lima 162

    Exemplo Trigger Instead Ofcreateorreplacetriggerv_pessoas_iid

    instead of insert or delete on v pessoas

  • 5/20/2018 02_-_PLSQL (1)

    163/164

    insteadofinsertordeleteonv_pessoasdeclare

    beginifinserting thenif:new.tipo = 'P'theninsertintoprofessores

    ( cod_prof, cod_curso, nom_prof )values

    ( :new.codigo, :new.cod_curso, :new.nome );elsif:new.tipo = 'A'theninsertintoalunos

    ( mat_alu, cod_curso, dat_nasc, tot_cred, mgp, nom_alu )values

    ( :new.codigo, :new.cod_curso, '01/01/1990', 0, 0, :new.nome );elseraise_application_error( -20000, 'Tipo de pessoa invlida');

    endif;elseif:old.tipo = 'P'then

    deletefromprofessoreswherecod_prof = :old.codigo;

    elsif:old.tipo = 'A'thendeletefromalunos

    wheremat_alu = :old.codigo;

    endif;endif;

    end;Prof. Arquimedes Lima 163

    Exerccio

  • 5/20/2018 02_-_PLSQL (1)

    164/164

    1. Crie uma viso V_ALUNOS que possua todos os campos databela alunos e mais o cdigo e nome do curso do alunovinculado. Depois de criar a viso, crie uma trigger de InsteadOf de insert, update e delete. Quando for feito um insertdeve-se verificar se o curso j existe, caso no exista deve ser

    includo, caso exista deve ter o seu nome atualizado. Depoisda incluso do curso deve-se incluir o aluno, vinculando-oautomaticamente ao curso. No caso do update, deve-seatualizar a linha da tabela de alunos e a linha da tabela decursos conforme os valores passados na viso. No caso do

    deletedeve-se primeiramente excluir o aluno e depois excluiro curso Se algum outro aluno j possuir vnculo com este