PL/pgSQL por Diversão e Lucro



Documentos relacionados
Triggers no PostgreSQL

Sistemas de Informação

Laboratório de Banco de Dados Prof. Luiz Vivacqua. PL/pgSQL A Linguagem de programação do PostgreSQL

PROGRAMAÇÃO EM BANCO DADOS Stored Procedure e Trigger

PROGRAMAÇÃO EM BANCO DADOS Store Procedure e Trigger

BANCO DE DADOS II Prof. Ricardo Rodrigues Barcelar

FUNCTION ) RETURNS INTEGER AS $$ DECLARE

PL/pgSQL. Introdução. Introdução. Introdução

GBC043 - Sistemas de Banco de Dados Funções e Gatilhos no PostgreSQL

Bancos de Dados I. Integridade semântica

Triggers em PostgreSQL. Linguagem de Programação de Banco de Dados. Triggers em PostgreSQL. Triggers em PostgreSQL

Introdução às funções e procedimentos. SQL suporta funções e procedimentos úteis com tipos de dados específicos

SQL Procedural. Josino Rodrigues Neto

Triggers. um trigger permite que uma determinada sequência de comandos SQL seja accionada quando um determinado evento ocorre.

Oracle PL/SQL Overview

Triggers e Regras. Fernando Lobo. Base de Dados, Universidade do Algarve

Linguagens Procedurais no PostgreSQL: Funcoes. Linguagens Procedurais no PostgreSQL: Funcoes

Consultoria e Treinamento em Bancos de Dados Relacionais

PostgreSQL. André Luiz Fortunato da Silva Analista de Sistemas CIRP / USP alf@cirp.usp.br


Logado no OracleXE vamos acessar a opção:

Oracle 10g: SQL e PL/SQL

Banco de Dados II. Triggers e Functions. Prof. Moser Fagundes. Curso TSI Instituto Federal Sul-Rio-Grandense (IFSul) Campus Charqueadas


BANCO DE DADOS II Prof. Ricardo Rodrigues Barcelar

Bases de Dados 2012/2013 Funções/procedimentos e triggers. Helena Galhardas 2012 IST. Bibliografia. Manual referência PostgreSQL

SQL Gatilhos (Triggers)

BANCO DE DADOS. info 3º ano. Prof. Diemesleno Souza Carvalho

UNINGÁ UNIDADE DE ENSINO SUPERIOR INGÁ FACULDADE INGÁ CIÊNCIA DA COMPUTAÇÃO CURSORS. Profº Erinaldo Sanches Nascimento

PostgreSQL 8.0. Diogo Biazus

Bases de Dados 2007/2008. Aula 9

SQL DDL Criando Tabelas e Restrições

RECUPERAÇÃO DE CONTEÚDO BANCO DE DADOS

Relatório. Projecto de Base de Dados Parte 2. Turno: quinta-feira, 11:30 Grupo 25: André Gonçalves Rui Barradas Hélton Miranda 68477

Projeto de Banco de Dados

GES013 - Sistema de Banco de Dados Funções e Gatilhos no PostgreSQL

A linguagem SQL

Monitoria GDI Aula Prática. DML + PL/SQL parte 1

Usando PostgreSQL na Regra de Negócio de um ERP. Fabiano Machado Dias Eduardo Wolak

Lista 02 Sistema de Banco de Dados CAP 241 Computação Aplicada I

Introdução à Banco de Dados. Nathalia Sautchuk Patrício

Regras de Negócios é com o Elefante!

AULA 2 INTERAÇÃO COM O BANCO DE DADOS

Roteiro 9 - SQL Básico: chave estrangeira, operadores de comparação e operadores booleanos

Operação de União JOIN

Banco de Dados Avançados Banco de Dados Ativo

PL/SQL. Profa. Dra. Cristina Dutra de Aguiar Ciferri. Laboratório de Bases de Dados PL/SQL

8. Outros tipos de Transação (Modo de Transação de Autoconfirmação e Modo Implícito)

Introdução ao SQL. Aécio Costa

Introdução à Engenharia da Computação. Banco de Dados Professor Machado

Gatilhos (Triggers) Prof. Márcio Bueno Elaborado por Maria Lígia B. Perkusich

Comandos de Manipulação

Banco de Dados I. Aula 12 - Prof. Bruno Moreno 04/10/2011

AULA 8 CRIANDO UMA CLASSE EM PHP INTERAGINDO COM BANCO DE DADOS - COM RELACIONAMENTO ENTRE TABELAS

O dono de uma livraria cuja base de dados é administrada por si pediu-lhe para efectuar as seguintes alterações ao preço dos livros:

trigger insert, delete, update

PROCEDIMENTOS ARMAZENADOS (Stored Procedures)

Bases de Dados 2007/2008. Aula 8

Programando em SQL. Triggers, Stored Procedures e funções. Profa. Késsia Marchi

Faculdade Pitágoras 16/08/2011. Curso Superior de Tecnologia: Banco de Dados Sistemas para Internet

Faculdade Pitágoras. Curso Superior de Tecnologia: Banco de Dados. Disciplina: Banco de Dados Prof.: Fernando Hadad Zaidan SQL

Tarefa Orientada 19 Triggers

Transações Seguras em Bancos de Dados (MySQL)

2 echo "PHP e outros.";

APOSTILA BANCO DE DADOS INTRODUÇÃO A LINGUAGEM SQL

TECNOLOGIA EM SISTEMAS PARA INTERNET PROJETO DE BANCO DE DADOS

FERRAMENTA DE APOIO A REESTRUTURAÇÃO DE CÓDIGO FONTE EM LINGUAGEM PL/SQL BASEADO EM PADRÕES DE LEGIBILIDADE

Criação de Log de Ações Através do Banco de Dados. Marcos Thomaz da Silva

SQL comando SELECT. SELECT [DISTINCT] <campos> FROM <tabela> [condição] [ ; ] Paulo Damico - MDK Informática Ltda.

Programação SQL. Introdução

EXEMPLOS DE COMANDOS NO SQL SERVER

PHP INTEGRAÇÃO COM MYSQL PARTE 1

BANCO DE DADOS: SQL. Edson Anibal de Macedo Reis Batista. 27 de janeiro de 2010

PCS3413. Engenharia de So-ware e Banco de Dados. Aula 20. Escola Politécnica da Universidade de São Paulo

Administração de Banco de Dados

Armazenamento organizado facilitando SCRUD; Agiliza processo de desenvolvimento de sistemas;

4.6. SQL - Structured Query Language

Auditoria de sistemas Deixe que seu banco de dados faça o trabalho por você

Create Sequence Cria uma sequence. Uma sequence é um objeto que permite vários usuários gerarem valores inteiros sem repetição.

Listando itens em ComboBox e gravando os dados no Banco de Dados MySQL.

O que são Bancos de Dados?

SQL TGD/JMB 1. Projecto de Bases de Dados. Linguagem SQL

2. Criar um bloco PL/SQL anônimo para imprimir as tabuadas abaixo: 5 X 10 = 50 5 X 2 = X 10 = X 2 = 2...

Leonardo Gresta Paulino Murta

Integridade dos Dados

Tarefa Orientada 15 Manipulação de dados

Neste artigo, serão apresentados os principais conceitos sobre os TRIGGERS e sua aplicabilidade.

AULA 2 INTERAÇÃO COM O BANCO DE DADOS

Avisos. Sumário. Atividade em lab Aula 29. Atividade em lab Aula 29. Programando com SQL Triggers EXERCÍCIO LAB SP. Vista da segunda prova

SQL - Criação de Tabelas

SQL (Structured Query Language)

Acesso a Bancos de Dados em Java (JDBC)

Hugo Pedro Proença, 2007

Procedimentos armazenados

Controle de transações em SQL

Transcrição:

PL/pgSQL por Diversão e Lucro Roberto Mello 3a. Conferência Brasileira de PostgreSQL - PGCon-BR Campinas - 2009 1

Objetivos Apresentar as partes principais do PL/pgSQL Apresentar casos de uso comum do PL/pgSQL Apresentar alguns casos do que NÃO fazer com PL/ pgsql Apresentar os diferentes tipos de gatilhos Como criar gatilhos com PL/pgSQL Exercícios para prática Resolver dúvidas (ou pelo menos tentar) 2

Como aproveitar melhor Tenha a documentação em mãos http://www.postgresql.org/docs/8.4/static/ Tenha o PostgreSQL instalado no seu laptop Se não tiver, pode escrever no seu editor de texto favorito, ou mesmo em papel Estou usando exemplos simples, vários dos quais seriam melhor feitos direto em SQL, ao invés de PL 3

Modelo de Dados CREATE TABLE vendedores( vendedor_id SERIAL NOT NULL PRIMARY KEY, nome varchar(256)); INSERT INTO vendedores VALUES (DEFAULT, Fabio ), (DEFAULT, Joao ), (DEFAULT, Leonardo ); CREATE TABLE vendas( item_id integer, vendedor_id integer REFERENCES vendedores.vendedor_id, quantidade integer, preco numeric); INSERT INTO vendas VALUES (1, 1, 5, 142), (2, 3, 54, 45), (3, 2, 21, 467), (4, 2, 32, 343), (5, 1, 21, 235);; 4

PL/pgSQL É uma linguagem de procedimentos (mas não é a única aceita no PostgreSQL) Adiciona estrutura e controle ao SQL É parecida com outras linguagens da família C Roda dentro do servidor, evitando a viagem e conversões entre cliente e servidor Um dos seus principais usos é em gatilhos Acesso à todas as funcionalidades do SQL 5

Estrutura CREATE OR REPLACE FUNCTION uma_funcao(preco numeric) RETURNS integer AS $$ DECLARE -- declarações de variáveis quantidade integer := 30; BEGIN -- expressões, consultas, cálculos, etc RETURN quantidade * preco; END; $$ LANGUAGE plpgsql; 6

Parâmetros Podem ser de entrada (IN) ou saída (OUT) CREATE OR REPLACE FUNCTION calc_item(p_item_id int, OUT quantidade int, OUT total numeric) AS $$ BEGIN SELECT vendas.quantidade, vendas.quantidade * vendas.preco INTO quantidade, total FROM vendas WHERE item_id = p_item_id; END; $$ LANGUAGE plpgsql; Últimos valores atribuídos às variáveis de saída são os que valem Uso de RETURN seria redundante 7

Blocos CREATE OR REPLACE FUNCTION uma_funcao() RETURNS integer AS $$ << fora >> DECLARE quantidade integer := 30; BEGIN RAISE NOTICE 'Quantidade aqui %', quantidade; -- 30 quantidade := 50; -- -- Criamos um sub-bloco -- DECLARE quantidade integer := 80; BEGIN RAISE NOTICE 'Quantidade aqui %', quantidade; -- 80 RAISE NOTICE 'Quantidade de fora aqui %', fora.quantidade; -- 50 END; RAISE NOTICE 'Quantidade aqui %', quantidade; -- 50 RETURN quantidade; END; $$ LANGUAGE plpgsql; 8

Sobre transações Uma função PL/pgSQL e todos os seus blocos roda INTEIRAMENTE dentro de uma transação BEGIN e END dentro de uma função são para delinear os blocos, e não para controlar transações Dentro da função não há como alterar a transação da função (e.g. COMMIT/ROLLBACK) Pode-se criar sub-transações dentro da função usando controle de exceções (a ser visto mais adiante) 9

Operadores variavel := expressao expressao será avaliada como SQL e deve retornar um valor escalar *, +, -, / Qualquer outro operador permitido pelo mecanismo de SQL 10

Exercício 1 Crie uma função que aceite 2 números inteiros e retorne a soma dos dois números 11

Executando Consultas SQL que não retorna registros pode ser executado diretamente. CREATE FUNCTION remarca( p_item_id int, p_pct int) RETURNS NULL AS $$ DECLARE novo_preco numeric DEFAULT 0; BEGIN UPDATE vendas SET preco = preco + 1 WHERE item_id = p_item_id; -- Usando PERFORM ao invés de SELECT descartará todos -- os resultados que sejam retornados PERFORM remarca_todos(); -- Variável especial FOUND IF FOUND THEN raise notice resultados descartados ; END IF; END; $$ LANGUAGE plpgsql; 12

Executando Consultas Resultados de consultas precisam ser postos em variáveis CREATE FUNCTION remarca( p_item_id int, p_pct int) RETURNS numeric AS $$ DECLARE novo_preco numeric DEFAULT 0; BEGIN UPDATE vendas SET preco = preco + (preco * 1/p_pct) WHERE item_id = p_item_id RETURNING preco INTO novo_preco; RETURN novo_preco; END; $$ LANGUAGE plpgsql; 13

Executando Consultas Do mesmo jeito para SELECT, INSERT, DELETE SELECT expressões_select INTO [STRICT] alvo FROM...; INSERT... RETURNING expressões INTO [STRICT] alvo; UPDATE... RETURNING expressões INTO [STRICT] target; DELETE... RETURNING expressões INTO [STRICT] alvo; 14

Exercício 2 Crie uma função que: Receba um identificador de um vendedor Retorne a soma das vendas daquele vendedor 15

Registros Variáveis do tipo RECORD armazenam registros inteiros DECLARE uma_venda RECORD; BEGIN SELECT * INTO uma_venda FROM vendas WHERE item_id = p_item_id; RAISE NOTICE Preco: %,uma_venda.preco; 16

Estruturas de Controle IF var <> 0 THEN faça algo ELSIF var >= 2 THEN faça outra coisa ELSE trate casos extras END IF; FOR i IN 1..10 LOOP --i irá de 0 a 10 --no laço END LOOP; WHILE preco > 410 LOOP RAISE NOTICE Bom Lucro ; END LOOP; CASE vendedor WHEN 1, 3 THEN faca algo aqui ELSE outros calculos END CASE; CASE WHEN vendedor = 1 THEN comissao := 100; WHEN vendedor = 2 THEN comissao := 60; ELSE comissao := 30; END CASE; 17

Passando pelos Resultados de Consultas DECLARE v_vendedores RECORD; BEGIN FOR v_vendedores IN SELECT * FROM vendedores ORDER BY vendedor_id LOOP RAISE NOTICE %, v_vendedores.nome; END LOOP; 18

Exercício 3 Crie uma função que receba um vendedor_id e imprima Parabens! para cada venda (tabela vendas) que o total (preco * quantidade) da venda tenha passado de 800 19

Retornando Múltiplos Registros CREATE OR REPLACE FUNCTION calc_item(p_item_id int) RETURNS TABLE (quantidade int, total numeric) AS $$ BEGIN RETURN QUERY SELECT vendas.quantidade, vendas.quantidade * vendas.preco FROM vendas WHERE item_id = p_item_id; END; $$ LANGUAGE plpgsql; RETURNS TABLE é o mesmo que declarar vários parâmetros OUT e especificar RETURNS SETOF umtipo 20

Retornando Múltiplos Registros CREATE OR REPLACE FUNCTION getallfoo() RETURNS SETOF foo AS $BODY$ DECLARE r foo%rowtype; BEGIN FOR r IN SELECT * FROM foo WHERE fooid > 0 LOOP -- pode-se fazer processamento aqui RETURN NEXT r; -- returna o registro corrente do SELECT END LOOP; RETURN; END $BODY$ LANGUAGE 'plpgsql'; 21

Retornando Múltiplos Registros CUIDADO!! RETURN NEXT e RETURN QUERY armazenam TODO o resultado na memória antes de retornar, o que causa uso exagerado de memória e disco se o resultado for de muitos registros 22

Cursores Cursores são resultados de consultas que se pode ir e voltar na lista dos resultados, ao invés de só adiante São eficientes no que diz respeito ao uso de memória Só podem ser usados dentro de uma transação Operações: FETCH [ direction { FROM IN } ] cursor INTO target; MOVE [ direction { FROM IN } ] cursor; UPDATE table SET... WHERE CURRENT OF cursor; DELETE FROM table WHERE CURRENT OF cursor; 23

Cursores CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$ BEGIN OPEN $1 FOR SELECT * FROM table_1; RETURN NEXT $1; OPEN $2 FOR SELECT * FROM table_2; RETURN NEXT $2; END; $$ LANGUAGE plpgsql; -- precisa estar numa transação para usar cursores. BEGIN; SELECT * FROM myfunc('a', 'b'); FETCH ALL FROM a; FETCH ALL FROM b; COMMIT; 24

Gatilhos Funções que são chamadas automaticamente antes (before) ou depois (after) de Insert, Update, Delete, Truncate Função tem que ser declarada específicamente como de gatilho, e um CREATE TRIGGER tem que ser rodado por tabela sobre a qual o gatilho incidirá 25

Gatilhos - variáveis NEW - armazena o novo registro em insert/update OLD - armazena o registro velho em UPDATE/DELETE TG_NAME - nome do gatilho disparado TG_WHEN - string contendo BEFORE ou AFTER TG_LEVEL - string com ROW ou STATEMENT dependendo do gatilho TG_OP - string com INSERT, UPDATE, DELETE, or TRUNCATE indicando a operação TG_RELID - oid da tabela que chamou o gatilho TG_TABLE_NAME - nome da tabela que chaou o gatilho TG_TABLE_SCHEMA - nome do esquema da tabela que chamou o gatilho TG_NARGS - número de argumentos dados à função do gatilho no CREATE TRIGGER TG_ARGV[] - matriz com os argumentos dados no CREATE TRIGGER 26

Gatilhos CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$ BEGIN IF NEW.empname IS NULL THEN RAISE EXCEPTION 'empname não pode ser nulo'; END IF; IF NEW.salary IS NULL THEN RAISE EXCEPTION '% não pode ter salário nulo', NEW.empname; END IF; IF NEW.salary < 0 THEN RAISE EXCEPTION '% não pode ter salário negativo', NEW.empname; END IF; -- Lembre quem mudou a folha, e quando NEW.last_date := current_timestamp; NEW.last_user := current_user; RETURN NEW; END; $emp_stamp$ LANGUAGE plpgsql; CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp FOR EACH ROW EXECUTE PROCEDURE emp_stamp(); 27

Exercício 4 Crie uma função de gatilho que insira um novo registro na tabela comissoes cada vez que um vendedor fizer uma nova venda (tabela vendas) cujo preço seja maior que 400 A comissão deverá ser de 15% do valor da venda Tabela comissoes tem colunas: comissao_id, vendedor_id, item_id, comissao 28

Armadilhas a serem evitadas Programadores inexperientes em SQL tentam fazer tudo em PL/pgSQL, ao invés de procurar a maneira idiomática (e geralmente muito mais rápida) de se fazer em SQL Consultas dentro de funções também precisam ser testadas e otimizadas, senão viram buraco negro Mudanças de dados em gatilhos não devem ser silenciosas: erros tem que ser notificados à aplicação para que ela seja corrigida 29

Ex: Gatilho errôneo BEGIN /* Don t allow date_created or created_by fields to be updated */ IF ( UPDATE = TG_OP) THEN bool_has_column := func_table_has_column(tg_relname::varchar, created_by ); IF bool_has_column THEN NEW.created_by = OLD.created_by; END IF; NEW.date_created = OLD.date_created; END IF; RETURN NEW; END; Dados são mudados slienciosamente, sem log 30

Perguntas? robertomello@2reng.com.br 31