Upload
alucard2012
View
43
Download
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