• Nenhum resultado encontrado

Triggers-procedures

N/A
N/A
Protected

Academic year: 2021

Share "Triggers-procedures"

Copied!
50
0
0

Texto

(1)

Fundamentos de Bancos de

Dados

José Maria Monteiro

Departamento de Computação

Universidade Federal do Ceará

(2)

Sumário

Stored Procedures;

Triggers;

(3)

Stored Procedures

Coleção de comandos SQL

Mecanismo semelhante ao RPCCódigo sob o controle do SGBDPassagem de parâmetros

Desempenho melhor por estar

“mais próximo” dos dados

Diminui tráfego de rede

Aplicação Stored Procedures exec procedure retorna resultado

(4)

Stored Procedures

Funções

Regras de negócio e integridade dos dados no SGBDAdministração do sistema

Lado “servidor” da lógica da aplicação

Características

Comandos SQL compartilhados por aplicaçõesMelhor desempenho em ambientes C/S

(5)

Stored Procedures

Menor flexibilidade

Pode piorar desempenho se o plano de execução

não for periodicamente refeito

Cada procedure é por default uma transação

separada

Falta de padronização/portabilidade!!!

(6)

Triggers

insert update delete Eventos Ação Comando SQL Stored Procedure SGBD ativo Reação automática a eventos monitorados

(7)

Triggers

Usar 650 parafusos “estoque de parafusos: 850” parafusos 1500 850 Se quantidade de parafusos em estoque é menor que 1000, então “acordar” comprador

= > comprar 1000

(8)

Trigger - Exemplo

DEFINE TRIGGER Departamentos D, Empregados E,

Empregados G:

WHERE E.Salario > G.Salario AND E.CDep = D.Codigo AND

D.Gerente = G.CPF

ACTION_PROCEDURE(NOTIF_GERENTE(D.Gerente); Notificar o gerente se qualquer empregado do seu

(9)

Postgres

Diferente dos outros SGBDs:

Store Procedures e triggers são tratados como funções.Presença de diversas linguagens procedurais para

programação de funções diretamente no banco de dados.

(10)

Qual a vantagem de utilizar PL/pgSQL?

Praticidade da utilização de comandos SQLs integrados à

linguagem e na criação de cache dessas consultas.

Oficialmente distribuidas com o servidor:

PL/pgSQL, PL/TCL, PL/Python e PL/Perl. Podem ser instaladas:

PL/Java, PL/Ruby, PL/R.

Flexibilidade obtida separando o mecanismo do banco de

dados do executor das funções.

(11)

PL/pgSQL

Executa comandos SQL diretamente no corpo dos

procedimentos.

Segura, ambiente de execução é restrito ao SGBD. Uso de cache otimizado.

A programação é feita em blocos:

DECLARE

... Declaração de Variáveis BEGIN

... Comando PL/pgSQL END

(12)

PL/pgSQL

IF condição 1 THEN

Seqüência de comandos 1 ELSIF condição 2 THEN

Seqüência de comandos 2 ELSE

Seqüência de comandos 3 END IF;

(13)

PL/pgSQL

LOOP Seqüência de comandos END LOOP; 

Estruturas de Controle

LOOP IF condição THEN Seqüência de comandos EXIT; END IF; END LOOP;

(14)

PL/pgSQL

WHILE condição LOOP

Seqüência de comandos END LOOP;

Estruturas de Controle

FOR contador IN

[REVERSE] X..Y LOOP

Seqüência de comandos END LOOP;

(15)

PL/pgSQL

Tratamento de Exceção:

RAISE NOTICE ‘%’, var ; (mensagem)

RAISE NOTICE ‘Texto qualquer’;

(16)

PL/pgSQL

Custo é alto, usar somente se necessário

Bloco de Exceção:

BEGIN comandos

EXCEPTION WHEN condição THEN comandos de tratamento

WHEN condição THEN comandos de tratamento END;

(17)

PL/pgSQL

Funções armazenadas (“stored procedures”)

Triggers

(18)

PL/pgSQL

Funções armazenadas:

CREATE FUNCTION atualizaValor ( valor varchar ) RETURNS boolean

CREATE [ OR REPLACE ] FUNCTION

name ( [ [ argname ] argtype [, ...] ] ) RETURNS rettype

Onde rettype pode ser :

1. Tipo primitivo

2. Estrutura composta 3. Tipo do domínio

(19)

Funções armazenadas:

PL/pgSQL

CREATE FUNCTION primeira_funcao() RETURNS VOID AS $body$ BEGIN RETURN; END; $body$ LANGUAGE 'plpgsql';

(20)

Imprime a mensagem “Minha primeira rotina em

PL/pgSQL”:

Exemplo PL/pgSQL

CREATE OR REPLACE FUNCTION primeira_funcao() RETURNS VOID AS

$body$ BEGIN

RAISE NOTICE 'Minha primeira rotina em PL/pgSQL'; RETURN;

END; $body$

LANGUAGE 'plpgsql';

CREATE OR REPLACE FUNCTION primeira_funcao() RETURNS VOID AS

$body$ BEGIN

RAISE NOTICE 'Minha primeira rotina em PL/pgSQL'; RETURN;

END; $body$

(21)

Executando uma FUNCTION

Exemplo PL/pgSQL

select primeira_funcao()

(22)

PL/pgSQL

Declarando variáveis:

Atribuindo valores: numero := 15; Declarando variáveis: DECLARE

(23)

PL/pgSQL

Executando SQL:

CREATE OR REPLACE FUNCTION exclui_cliente(pid_cliente Integer) RETURNS Integer

AS $body$ DECLARE

vLinhas Integer DEFAULT 0; BEGIN

DELETE FROM clientes WHERE id_cliente = pid_cliente; GET DIAGNOSTICS vLinhas = ROW_COUNT;

RETURN vLinhas; END;

$body$

(24)

Executando uma FUNCTION

select exclui_cliente(3)

select exclui_cliente(3)

(25)

PL/pgSQL

CREATE OR REPLACE FUNCTION media_compras(pid_cliente Integer) RETURNS numeric AS $body$ DECLARE linhaCliente Clientes%ROWTYPE; mediaCompras real; totalCompras real; periodo Integer; BEGIN

SELECT * INTO linhaCliente FROM clientes WHERE id_cliente = pid_cliente; periodo := age(current_date, linhaCliente.data_inclusao);

SELECT SUM(valor_total) INTO totalCompras FROM pedidos WHERE id_cliente = pid_cliente;

mediaCompras := totalCompras / periodo; RETURN mediaCompras;

END;

$body$ LANGUAGE 'plpgsql';

Variável armazena uma linha da tabela Clientes

Variável armazena resultado da consulta Atribuição

(26)

Exemplo

Na tabela Aluno

Criar função armazenada ( “stored procedure”)

para atualizar o valor currículo do aluno.

Parâmetros

valor novo para currículoNum_matricula

(27)

CREATE FUNCTION atualizaCurriculo(varchar valorNovo, varchar mat) RETURNS boolean AS

$$

BEGIN

UPDATE aluno SET curriculo = $1 WHERE num_matricula = $2;

RETURN FOUND; END;

$$

LANGUAGE 'plpgsql' ;

CREATE FUNCTION atualizaCurriculo(varchar valorNovo, varchar mat) RETURNS boolean AS

$$

BEGIN

UPDATE aluno SET curriculo = $1 WHERE num_matricula = $2; RETURN FOUND; END; $$ LANGUAGE 'plpgsql' ; $1, $2 são parâmetros passados pela chamada da função

palavra reservada do sistema; booleano que retorna true sse houve alteração

(28)

PL/pgSQL

Cursor:

Áreas de memória utilizadas pelo PostgreSQL para

armazenar registros enquanto eles são processados.

Usados para percorrer as relacões e processar

conjuntos de dados.

Criada por resultado de COMMIT, ROLLBACK,

INSERT, SELECT , UPDATE, DELETE

(29)

PL/pgSQL

cursor1 refcursor

(30) ;

cursor2 CURSOR FOR

SELECT * FROM tab1 ;

cursor3 CURSOR (chave integer) IS SELECT *

FROM tab1

WHERE unique1 = chave;

cursor1

refcursor;

(30)

Uso do cursor

1.

Declarar ( declare )

2.

Abrir ( open )

3.

Navegar/ Atribuir os valores ( fetch )

4.

Fechar ( close )

* Postgres: invocação de função com cursor

deve ocorrer dentro de transação

(31)

PL/pgSQL

OPEN FOR SELECT

OPEN FOR EXECUTE

Abrir cursor:

OPEN cursor FOR SELECT query ;

OPEN cursor FOR EXECUTE

(32)

Abrir cursor para SELECT

Cursor sem limite ( cursor refcursor )

(33)

create function cursorLerAluno(varchar) returns text as $$ declare c refcursor; nm aluno.nome%type; cur aluno.curriculo%type; begin

OPEN c FOR SELECT nome, curriculo from aluno where num_matricula = $1;

fetch c into nm, cur; close c;

return nm || ','|| cur; end;

$$ language 'plpgsql';

(34)

Abrir cursor para EXECUTE

Cursor sem limite

Palavra reservada EXECUTE

EXECUTE pede string ( usar apóstrofo ) Situações de SQL dinâmico ( passagem dos

parâmetros como tabela , comando )

Pode-se usar uma variável que armazena o

(35)

create or replace function cursorLerAluno(varchar) returns text as $$ declare c refcursor; nm aluno.nome%type; cur aluno.curriculo%type; begin

OPEN c FOR EXECUTE 'SELECT nome, curriculo from aluno where num_matricula ='|| $1;

fetch c into nm, cur; close c;

return nm || ','|| cur; end;

$$

language 'plpgsql';

(36)

PL/pgSQL

FETCH direction [ count ] { IN | FROM } cursor

direction ::= { FORWARD | BACKWARD |

RELATIVE }

count ::= { numrows | ALL | NEXT | PRIOR }

FETCH Cursor:

(37)

create or replace function teste() returns boolean as $body$ declare c refcursor; reg aluno%rowtype; i integer; tot integer; begin

OPEN c FOR SELECT * from aluno ; SELECT count(*) INTO tot from aluno; i:=1;

FOR i IN 1..tot LOOP FETCH c INTO reg;

raise notice '%', reg.nome ;

raise notice '%', reg.num_matricula ; END LOOP; close c; RETURN FOUND; end; $body$ language 'plpgsql‘;

FETCH Cursor

(38)

CREATE OR REPLACE FUNCTION cursor_empregado() RETURNS void AS $BODY$

DECLARE

cursor1 CURSOR IS SELECT * FROM EMPREGADO; emp empregado%ROWTYPE;

BEGIN

open cursor1;

fetch cursor1 into emp; loop

exit when not found;

RAISE NOTICE ‘Empregado de id: %‘, emp.id; fetch cursor1 into emp;

end loop; close cursor1; END; $BODY$ LANGUAGE 'plpgsql' VOLATILE ;

PL/pgSQL

Declara a váriável

cursor Abre o cursor

Coloca a próxima linha do cursor na váriável

(39)

Triggers (Gatilhos)

Função trigger pode ser escrita em C ou em

qualquer outra linguagem procedural.

Iremos utilizar o PL/pgSQL.

Função trigger é uma função declarada sem

argumentos e retorna um tipo de dados trigger.

Uma mesma função trigger pode ser utilizada

em vários triggers.

Um trigger só pode ser definido depois que a

sua função trigger já estiver criada.

(40)

Postgres

Triggers (Gatilhos)

Ele é invocado (disparado) quando ocorre uma

tentativa de modificação nos dados da tabela (relação) à qual ele está associado (vinculado).

Os triggers podem ser invocados por cada

linha afetada ou por cada comando INSERT, UPDATE ou DELETE.

Podem ser definidos para executar antes ou

depois de qualquer modificação no banco de dados.

(41)

Postgres

Triggers (Gatilhos)

Os triggers são usados para garantir regras de

negócio e integridade dos dados, ou para ações complexas, tais como automaticamente atualizar um resumo dos dados.

Caso a execução de um trigger possa violar

alguma restrição, então ele não será executado.

(42)

Exemplo Triggers PL/pgSQL

Suponha duas tabelas: Estudante e Exame.Estudantes fazem exames.

Não utilizamos FOREIGN KEY na tabela

Exame.

Escreva uma função trigger para forçar uma

restrição de integridade entre as tabelas Exame e Estudante.

Estudante(mat integer, nome varchar(20))Exame(eid integer, enome varchar(15))

(43)

Criação das tabelas

CREATE TABLE Estudante (mat INTEGER, name VARCHAR(20));

CREATE TABLE Exame (eid INTEGER, enome VARCHAR(20));

(44)

Função trigger escrita em PL/pgSQL

CREATE OR REPLACE FUNCTION restr_integr()

RETURNS trigger AS ‘

DECLARE estudantes RECORD; BEGIN

SELECT * INTO estudantes FROM Estudante WHERE NEW.mat = mat; IF NOT FOUND THEN

RAISE NOTICE \’Estudante inexistente! %\’, NEW.mat; RETURN NULL; ELSE RETURN NEW; END IF; END; ‘ LANGUAGE ‘PLpgSQL’;

(45)

Criação do Trigger

CREATE TRIGGER rest_trigger

BEFORE INSERT ON Exame

FOR EACH ROW

(46)

Entendendo a síntaxe...

CREATE OR REPLACE: Sem este comando, ao modificar

a definição de uma função, você deve removê-la primeiro.

AS ‘ ... ‘ : O corpo da função deve estar entre as aspas

simples.

DECLARE estudante RECORD: a variável estudante pode

armazenar uma informação de uma linha.

NEW.mat: Como o trigger é antes do INSERT, NEW

corresponde a nova linha a ser inserida.

RAISE NOTICE: Usado para mostrar um erro.

RETURN NULL: Skip a inserção da tupla.

(47)

Inserir tuplas…

Inserir os seguintes estudantes:

Insert INTO Estudante VALUES (1,’José’); Insert INTO Estudante VALUES (2,’João’);

(48)

Ao tentar inserir na tabela de Exames, como o

estudante de mat=1 já existe, o trigger deverá permitir a inserção:

Já a seguinte inserção, na tabela Exame não deve

ser permitida:

Agora, tente inserir em Exame...

Insert INTO Exame VALUES (1,’FBD I’);

(49)

declare

dataFrequencia char(20);

timestampFrequencia timestamp;

dataFrequencia = ano || '-' || mes || '-' || dia;

timestampFrequencia = CAST (dataFrequencia AS timestamp);

(50)

now();

date_part(year, freq_data); CAST ($2 AS character);

timestampFrequencia = CAST ('2009-11-' || diaFrequencia AS timestamp);

CAST (date_part('month', freq_data) as integer);

Referências

Documentos relacionados

(SELECT count(*) AS N FROM (SELECT DISTINCT (Custnum) AS QtdClient, Year([Order Date]) AS AnoCompra FROM Orders GROUP BY Year([Order Date]), Custnum HAVING (Year(Orders.[Order

A Evolução dos Direitos Fundamentais na União Europeia e a Questão da Adesão à Convenção Europeia dos Direitos Humanos à Luz da Opinião nº 2/13 do Tribunal de Justiça da

Como bolsistas do Programa Institucional de Bolsas de Iniciação à Docência – PIBID, do subprojeto área Matemática e estagiária pela disciplina de Estágio

Multithreading Non-Preemptive -- sequential version function Receive(connection) return connection:receive(2^10) end -- concurrent version function Receive(connection)

O objetivo deste trabalho é aprimorar a ferramenta web CodeMaster, para fazer análise e avaliação automática de design de interface de aplicativos desenvolvidos

O objetivo do presente relato de caso é relatar a perda de integridade de primeiros molares permanentes superiores e a importância da educação em saúde como forma de prevenção

financiamento da instalação do equipamento utilizado e das respectivas despesas de manutenção. 2 - A autorização de instalação pode também ser requerida pelo presidente da

Aproveitando duas grades de pesquisa instaladas nas savanas de Roraima pelo Programa de Pesquisas em Biodiversidade (PPBio), este trabalho possui como meta primária inventariar as