Académique Documents
Professionnel Documents
Culture Documents
Procedimento armazenado
um programa similar a uma funo.
A explicao da aula comparada com a resoluo do exerccio Aula 7. Ento ser percebida a diferena entre funo e procedimento.
Funo X Procedimento Neste exemplo, vamos comparar a soluo da Aula7 feita para funo e ver a mesma soluo em procedimento armazenado: -- Resoluo por funo:
create or replace function func_relat_emp (p_id number) return number is v_nome_dep c_depto.nome%type; v_qtd number(10);
cursor c_empreg (P_dep number) is select id, prim_nome|| ' ' || ult_nome as nome_emp from c_empr where id_Depto = p_dep; begin select nome into v_nome_dep from c_depto where id = p_id; for r_emp in c_empreg(p_id) loop
insert into emp_relatorio values (r_emp.id, r_emp.nome_emp, v_nome_dep); v_qtd := c_empreg%rowcount; end loop; commit;
return v_qtd;
end;
Out - sada
( p_dep in number, p_qtd out number) -- observe que alem do paramentro ( p_dep) de entrada por ser um -- existe um parametro de sada ( p_qtd). as cursor c_relat_emp (p_depto in number) is select e.id, e.prim_nome || ' ' || e.ult_nome as emp_nome, d.nome procedimento
from c_empr e inner join c_depto D on e.id_depto = d.id where e.id_depto = p_depto;
-----
no cursor do procedimento se fez a opo de realizar a juno com c_depto para pegar o nome do departamento, repare que na funo o nome do departamento foi obtido na consulta select into. Qualquer das duas solues pode ser utilizada.
begin for r_emp in c_relat_emp(p_dep) loop insert into emp_relatorio values (r_emp.id, r_emp.emp_nome, r_emp.nome); p_qtd := c_relat_emp%rowcount; -- observe a atribuio do valor ao paramentro de saida e a ausencia -- do comando return. end loop; end;
Procedimento, quando for executado, vai at o fim, mesmo que encontre um exit ou break no meio do cdigo.
-- Exemplo de cdigo chamador -- Obs neste exemplo o modulo chamador alem de chamar a rotina proc_emp_relat,aps a execuo da mesmo insere na tabela emp_Relatorio o valor retornado pela rotina (v_qtd e a msg que este foi o valor retornado.
begin
proc_emp_relat(41,v_qtd); insert into emp_relatorio values (v_qtd, 'valor', 'voltou procedure'); end;
Gatilho
uma sub-rotina q executada automaticamente de acordo com uma determinada situao. Existem gatilhos de 2 tipos: DML (Reagem a Insert, Update e Delete) Eventos de BD (Ex: Shutdown, login, etc..)
Trabalharemos apenas com o gatilho DML. Estes gatilhos podem ser AFTER ou BEFORE, ou ainda, INSTEAD OF: AFTER: Primeiro ele faz o comando DML e depois faz a lgica do gatilho
INSTEAD OF: Ao receber um comando DML, ele o substitui pelo gatilho. Este gatilho permite, por exemplo, atualizar ou inserir dados em uma viso originada de 2 tabelas com Join.
Dentro de gatilho no pode ter controle de transao (COMIT e ROLLBACK). Os gatilhos podem ser em nvel de LINHA ou de COMANDO. Ex: Preciso fazer um gatilho que atue na atualizao de 10 linhas de uma tabela. Se resolvido com gatilho de LINHA: Este gatilho ser executado 10 vezes, 1 para cada linha. Se resolvido com COMANDO: Este gatilho ser executado 1 vez, e far a atualizao das 10 linhas da tabela.
Uma das maiores necessidades de utilizao de gatilhos manter os dados derivados atualizados. Ex: Idade, Clculo de saldo de Conta Corrente.
-Fazer um gatilho na tabela movimento que dispare ao ser inserido um novo registro na tabela e atualize a saldo da conta corrente do cliente na tabela conta_corrente. Para realizar o trabalho, crie as tabelas abaixo e popule a tabela de conta corrente utilizando os comandos abaixo
create table conta_corrente (nr number(6) primary key, nome varchar2(40), CPF char(11), saldo number(11,2));
Create table mov_cc (nr number(9) primary key, nr_cc number(6) references conta_corrente(nr), tipo char(1) not null, valor number(11,2)); insert insert insert insert insert insert into into into into into into conta_corrente conta_corrente conta_corrente conta_corrente conta_corrente conta_corrente values(101,'Carlos Rodrigues','12345678901',1020.45); values(111,'Jose Antonio Silva','67890154368',2045); values(121,'Carla Santos' ,'45698712345',3120.89); values(131,'Roberto Leito','12345678901',120); values(141,'Alberto Cesar','12345678901',2110.20); values(151,'Caio Domingues','12345678901',1000);
Soluo
create or replace trigger ins_mov_cc before insert on mov_cc for each row
Antes do INSERT Para cada linha (se omitido, vira gatilho de comando)
begin if upper(:new.tipo) = 'C' then update conta_corrente set saldo = saldo + :new.valor where nr = :new.nr_cc; elsif upper(:new.tipo) = 'D' then update conta_corrente set saldo = saldo - :new.valor where nr = :new.nr_cc; else raise_application_error (-20001, 'tipo nao valido'); end if; end;
:old
Chamada de um erro, pois ocorreu uma aplicao que no Crdito (C) nem dbito (D). O -20001 indica erro de usurio. At 2000 so erros prprios do Oracle.
um registro com o valor antigo na tabela (que foi sobrescrito pelo novo)
Observe acima que o saldo da conta 151 foi atualizado pelo gatilho. Mais um exemplo:
insert into MOV_CC values (2,111,'D',2000)
O saldo da conta 111 foi atualizado pelo gatilho. (Esqueci de mostrar isso no print. Faltou repetir o select. O valor de saldo da conta 111 ficou em R$45,00).