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



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

PL/pgSQL por Diversão e Lucro

BANCO DE DADOS II Prof. Ricardo Rodrigues Barcelar

FUNCTION ) RETURNS INTEGER AS $$ DECLARE

Consultoria e Treinamento em Bancos de Dados Relacionais

Bancos de Dados I. Integridade semântica

PROGRAMAÇÃO EM BANCO DADOS Stored Procedure e Trigger

Sistemas de Informação

Triggers no PostgreSQL

SQL Procedural. Josino Rodrigues Neto

PROGRAMAÇÃO EM BANCO DADOS Store Procedure e Trigger

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

Logado no OracleXE vamos acessar a opção:

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

Oracle PL/SQL Overview

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

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

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

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

BANCO DE DADOS II Prof. Ricardo Rodrigues Barcelar


Projeto de Banco de Dados

Oracle 10g: SQL e PL/SQL

A linguagem SQL

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

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

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

AULA 2 INTERAÇÃO COM O BANCO DE DADOS

PROCEDIMENTOS ARMAZENADOS (Stored Procedures)

AULA 2 INTERAÇÃO COM O BANCO DE DADOS

UFSM COLÉGIO AGRÍCOLA DE FREDERICO WESTPHALEN CURSO SUPERIOR DE TECNOLOGIA EM SISTEMAS PARA INTERNET. Programação para Internet I

SQL Gatilhos (Triggers)

APOSTILA BANCO DE DADOS INTRODUÇÃO A LINGUAGEM SQL

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

Laboratório de Banco de Dados II Aula 1. Stored Procedures

Tarefa Orientada 19 Triggers

trigger insert, delete, update

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


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

OPERADORES E ESTRUTURAS DE CONTROLE

RECUPERAÇÃO DE CONTEÚDO BANCO DE DADOS

Programação WEB I Estruturas de controle e repetição

Banco de Dados Avançados Banco de Dados Ativo

2 echo "PHP e outros.";

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

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

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

Tarefa Orientada 15 Manipulação de dados

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:

Persistência de Dados

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

SQL. Autor: Renata Viegas

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

MANUAL INSTALAÇÃO WEB SERVICE

Bases de Dados 2007/2008. Aula 8

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

Tabela de Símbolos. Análise Semântica A Tabela de Símbolos. Principais Operações. Estrutura da Tabela de Símbolos. Declarações 11/6/2008

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

Linguagem SQL Sub-linguagem DDL

Tarefa Orientada 18 Procedimentos armazenados

Programação SQL. Introdução

Comandos de Manipulação

JAVA NETBEANS PGOO Prof. Daniela Pires Conteúdo

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

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

PHP INTEGRAÇÃO COM MYSQL PARTE 1

António Rocha Nuno Melo e Castro

DESENVOLVIMENTO DE SOFTWARE

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

Treinamento sobre SQL

Podemos agora ver no IDE do Morfik os objetos que já incorporamos ao nosso projeto :

SQL DDL Criando Tabelas e Restrições

Structured Query Language (SQL)

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

Estrutura de Dados. Introdução a Ponteiros. Prof. Gerson Borges Estrutura de Dados I 1

LINGUAGEM SQL. SQL Server 2008 Comandos iniciais

Programação WEB II. PHP e Banco de Dados. progweb2@thiagomiranda.net. Thiago Miranda dos Santos Souza

Bases de Dados 2007/2008. Aula 9

Manipulando Strings no VBA (Replace, Mid e InStr)

Introdução ao SQL. Aécio Costa

FTIN FORMAÇÃO TÉCNICA EM INFORMÁTICA. Módulo de Programação Prof. Bruno Maciel

1. Domínio dos Atributos

Administração de Banco de Dados

Linguagem PL/SQL e Triggers

SQL Server Triggers Aprenda a utilizar triggers em views e auditar as colunas atualizadas em uma tabela

SQL Linguagem de Definição de Dados. Banco de Dados Profa. Dra. Cristina Dutra de Aguiar Ciferri

Hugo Pedro Proença, 2007

Sub AcessaWeb(url, x) ' recebe uma url para pesquisar e devolve uma planilha ' Solicita a criação da planilha x

Nesta aula serão apresentados alguns comandos de condição, repetição e gráficos.

Banco de Dados. Conversão para o Banco de Dados SisMoura

EXEMPLOS DE COMANDOS NO SQL SERVER

Integridade dos Dados

Persistência de Classes em Tabelas de Banco de Dados

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...

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

Transcrição:

Laboratório de Banco de Dados Prof. Luiz Vivacqua PL/pgSQL A Linguagem de programação do PostgreSQL 1) Visão Geral A PL/pgSQL é uma linguagem de programação procedural para o Sistema Gerenciador de Banco de Dados(SGBD) PostGreSQL. Uma linguagem procedural é uma linguagem de programação que é usada para especificar uma sequência de passos que são seguidos para produzir um resultado pretendido. Ela pode ser usada para agrupar sequências de comandos SQL com comandos de programação dentro do servidor de banco de dados, reduzindo a sobrecarga de rede e comunicação das aplicações cliente que precisam requisitar dados do banco. Através da linguagem pode-se: criar procedimentos de funções(stored procedures) e gatilhos(triggers) adicionar estruturas de controle a linguagem SQL realizar procedimentos complexos 2) Estrutura da linguagem A linguagem PL/pgSQL é estruturada em blocos. Um bloco é definido como: [ <<rótulo>> ] [ DECLARE declarações ] instruções END; O código do bloco principal começa com a seção de declaração DECLARE. O corpo do código começa com a palavra-chave e termina com a palavra chave END. O corpo deve retornar um valor do tipo especificado na palavra-chave RETURN. Todas as declarações e instruções dentro do bloco devem ser terminadas por ponto-e-vírgula. Um bloco contido dentro de outro bloco deve conter um ponto-e-vírgula após o END, entretanto, o END final que conclui o corpo da função não requer o ponto-e-vírgula. Todas as palavras chave e identificadores podem ser escritos misturando letras maiúsculas e minúsculas. Existem dois tipos de comentários no PL/pgSQL. O hífen duplo (--) começa um comentário que se estende até o final da linha. O /* começa um bloco de comentário que se estende até a próxima ocorrência de */. Os sub-blocos podem ser utilizados para agrupamento lógico, ou para limitar o escopo de variáveis a um pequeno grupo de instruções.

EXEMPLO: CREATE FUNCTION func_escopo() RETURNS integer AS DECLARE quantidade integer := 30; RAISE NOTICE 'Aqui a quantidade é %', quantidade; -- A quantidade aqui é 30 quantidade := 50; -- -- Criar um sub-bloco -- DECLARE quantidade integer := 80; RAISE NOTICE 'Aqui a quantidade é %', quantidade; -- A quantidade aqui é 80 END; RAISE NOTICE 'Aqui a quantidade é %', quantidade; -- A quantidade aqui é 50 RETURN quantidade; END; LANGUAGE plpgsql; => SELECT func_escopo(); NOTA: Aqui a quantidade é 30 NOTA: Aqui a quantidade é 80 NOTA: Aqui a quantidade é 50 func_escopo ------------- 50 OBS: 1)o comando RAISE NOTICE funciona como um display. 2)variáveis podem ser de qualquer tipo de dados suportado pelo SQL como integer, varchar, char, etc. Alguns exemplos: userid integer, quantidade numeric(5), url varchar. Variáveis de tipos: O %TYPE fornece o tipo de dado da variável ou da coluna da tabela. Pode ser usado para declarar variáveis que armazenam valores do banco de dados. Por exemplo, se existir uma coluna chamada id_usuario na tabela USUARIOS, podemos declarar uma variável com o mesmo tipo de dado desta coluna como: id_usuario usuarios.id_usuario%type; Usando-se %TYPE não há necessidade de conhecer o tipo de dado da estrutura referenciada. Além disso, se este tipo de dado for alterado, não haverá necessidade de mudar a definição da função. Variáveis de linha: Uma variável de tipo composto é chamada de variável de linha. Este tipo de variável pode armazenar toda uma linha de resultado de um comando SELECT. Os campos individuais são acessados usando a notação VARIAVEL_LINHA.CAMPO.

Uma variável_linha pode ser declarada como tendo o mesmo tipo das lnhas de uma tabela ou visão usando a notação: nome_da_tabela%rowtype; Variáveis de registro: Uma variável tipo-registro é semelhante a uma variável tipo-linha, mas não possuem uma estrutura pré-definida. Assumem a estrutura da linha para a qual é atribuída pelo comando SELECT em tempo de execução. create or replace function var_linha() returns varchar as 'Declare var disciplina%rowtype; resultado varchar; Begin select into var * from disciplina where codigo=''inf03''; resultado:= var.registro ''--'' var.nome; return resultado; End;' language 'plpgsql'; OBS: 1) A cláusula SELECT INTO pode ser usada para atribuir os resultados de um comando SELECT para uma lista de variáveis ou uma variável do tipo linha. Se uma linha ou lista de variáveis for usada como destino, os valores selecionados devem corresponder exatamente a estrutura do destino, senão ocorrerá um erro em tempo de execução. Se a consulta não retornar nenhuma linha, são atribuídos valores nulos aos destinos. Se a consulta retornar várias linhas, somente a primeira é atribuída ao destino enquanto as demais são desprezadas. 2) Usar 2 pliques '' ao invés de aspas quando fizer referência a algum literal. COMANDOS DE DESVIOS E INTERAÇÕES: Execução condicional: O PL/PGSQL possui 4 formas de IF: IF... THEN IF... THEN... ELSE IF... THEN... ELSE IF IF... THEN... ELSIF... THEN... ELSE IF-THEN É a forma mais simples. As instruções entre o THEN e o END são executadas se a condição for verdadeira. If v_nota <> 0 then Update histórico set nota=v_nota where matricula=v_matricula; end if; IF-THEN-ELSE A instrução IF-THEN-ELSE permite especificar um conjunto alternativo de instruções se a

condição for avaliada como FALSO. If v_nota <> 0 then Update histórico set nota=v_nota where matricula=v_matricula; eles Update histórico set nota=null where matricula=v_matricula; end if; IF-THEN-ELSE-IF Permite o aninhamento de IF, como no comando a seguir. if v_nota >= 6 then situacao:= aprovado else if nota < 6 then situacao := reprovado ; else situacao := sem nota ; end if; end if; IF-THEN-ELSIF Permite verificar muitas alternativas em uma instrução. Necessita de somente um END IF. IF temp = 25 THEN resultado := TEMPERADO ; ELSIF temp > 25 THEN resultado := QUENTE ; ELSIF temp < 25 THEN resultado := FRIO ; ELSE resultado := TEMP NULO ; END IF; TIPOS DE CONSTRUÇÕES DE REPETIÇÃO LOOP Define um laço incondicional repetido indefinidamente até ser terminado por uma instrução EXIT ou RETURN. Nos laços aninhados pode ser usado um rótulo na instrução EXIT para especificar o nível de aninhamento que deve ser terminado. Sintaxe: LOOP instruções EXIT Se nenhum rótulo for especificado, o laço mais interno é finalizado e a instrução após o END LOOP é executada a seguir. Se WHEN estiver presente, a saída do laço ocorre somente se a condição especificada for verdadeira, senão o controle passa para a instrução após o EXIT. Sintaxe: EXIT [rotulo] [WHEN expressao]

EXEMPLOS: LOOP ------ algum processamento if contador > 0 THEN EXIT; ----- sair do laço END IF; LOOP --------algum processamento EXIT WHEN contador > 0; ------ o mesmo do exemplo acima ------algum processamento if nota > 0 THEN EXIT; --------Erro: EXIT não pode ser usado for a de LOOP END IF; END; WHILE A instrucao WHILE repete a sequencia de instrucoes enquanto a expressão for avaliada como verdade. A expressão é verificada antes de cada entrada no corpo do laco. (sintaxe) WHILE expressão LOOP Instruções While contador < 10 LOOP --algum processamento Contador:=contador+1; FOR Cria um laco que interage em um intervalo de inteiros. A variavel usada no laco e definida automaticamente como do tipo integer e somente existe dentro do laco. Normalmente o passo da interacao é 1, mas quando REVERSE é especificado se torna -1. Sintaxe: FOR nome IN [REVERSE] expressao.. expressao LOOP Instrucoes Exemplos: FOR i in 1..10 LOOP --algum processamento RAISE NOTICE i is %, i;

FOR i in REVERSE 10..1 LOOP --algum processamento RAISE NOTICE i is %, i; Se o limite inferior for maior que o superior, o corpo do laco nao é executado nenhuma vez. LAÇOS ATRAVÉS DOS RESULTADOS DA CONSULTA Utilizando um tipo diferente de laco FOR, é possivel interagir atraves dos resultados de uma consulta e manipular os dados. Sintaxe: FOR registro_ou_linha IN comando LOOP Instrucoes Cada linha do resultado da consulta (um comando SELECT) é atribuida a variavel tipo-registro ou tipo-linha, e o corpo do laco é executado para cada linha. Create function teste_for_select() returns varchar as Declare Reg RECORD; Resultado varchar := Disciplinas: ; For reg in SELECT * FROM DISCIPLINA LOOP Resultado := resultado - reg.nome; Return resultado; END; Language plpgsql ; RETURN Toda funcao plpgsql deve terminar com uma instrucao RETURN. Existem duas formas de retorno: RETURN expressao; RETURN; A primeira forma deve ser usada quando a funcao retorna um valor simples enquanto que a segunda forma deve ser usada quando a funcao retorna um conjunto de valores. Quando a funcao retorna um conjunto de valores, é preciso executar uma ou mais vezes o comando RETURN NEXT que adiciona o resultado da funcao ao conjunto do resultado. Quando o conjunto do resultado estiver completo entao deve ser executado o comando RETURN simples. Create or replace function lista_notas(numeric) returns setof numeric as 'Declare reg_historico HISTORICO%ROWTYPE; FOR reg_historico in SELECT * from HISTORICO where matricula=$1

LOOP RETURN NEXT reg_historico.nota; RETURN; END;' Language 'plpgsql'; -- select lista_notas(100); CURSOR Um cursor pode ser visto como um nome para um result set. Ele deve ser declarado da mesma forma que qualquer outra variavel. O exemplo abaixo ilustra a declaracao de uma variavel cursor: Declare aluno_cursor cursor for SELECT * FROM ALUNO; Quando se declara uma variavel do tipo cursor, é necessario incluir a consulta associada. Antes de poder usá-lo, é necessário abrir o cursor com o comando OPEN. Declare aluno_cursor cursor for SELECT * FROM ALUNO; Open aluno_cursor; Após o cursor ser aberto as linhas podem ser recuperadas, uma de cada vez, com o comando FETCH. Para isso, deve ser informado uma ou mais variaveis destino para que o PL/PGSQL possa colocar os resultados da consulta. A sintaxe do comando é: FETCH nome_do_cursor INTO destino; O destino deve corresponder a forma da linha retornada pelo cursor. Por exemplo, se um cursor recupera linhas da tabela ALUNO, existem 3 possibilidades de variavel destino: a) uma variável do tipoaluno%rowtype; b) uma variável do tipo RECORD; c) três variáveis a saber: uma do tipo ALUNO.matricula%TYPE, outra do tipo ALUNO.nome%TYPE e a terceira do tipo ALUNO.escola%TYPE. Se for dado um FETCH apos a leitura de todos os registros a variavel boleana FOUND é atribuida para FALSO. Declare aluno_cursor cursor for SELECT * FROM ALUNO; aluno ALUNO%ROWTYPE; Open aluno_cursor; LOOP FETCH aluno_cursor INTO aluno; EXIT WHEN NOT FOUND;...... Close aluno_cursor; END;

CURSOR COM PARÂMETRO Quando se declara um cursor, é necessario especificar uma consulta. Muitas vezes nao se sabe exatamente os valores envolvidos na consulta no momento em que se esta escrevendo a funcao. Neste caso, um cursor parametrizado pode ser usado para resolver esta situacao. Quando o cursor for aberto, os valores para cada parametro devem ser fornecidos. Create or replace function lista_aluno(numeric) returns varchar as 'Declare aluno_cursor cursor(id numeric) FOR Select * from ALUNO where matricula=id; Aluno ALUNO%ROWTYPE; Mat numeric(4); Nome varchar; Mat := $1; Open aluno_cursor(mat); Fetch aluno_cursor into aluno; Nome:=aluno.nome; Return(nome); END;' Language 'plpgsql'; select lista_aluno(100); CURSOR DE REFERENCIA Quando uma variavel cursor e declarada, ela esta associada a uma consulta determinada. Se a consulta retorna linhas da tabela ALUNO ela sempre retornara linhas desta tabela. Uma variavel declarada como cursor de referencia pode ser usada para processar qualquer cursor. OBS: A sintaxe para declarar uma variavel com REFCURSOR é: declare ref_nome REFCURSOR; Repare que nao e especificada nenhuma consulta na declaracao da variavel. Ao invés disso, um cursor é associado ao REFCURSOR no momento da execucao. A grande vantagem deste tipo de variavel é poder passar a referencia para outra funcao. Create or replace function computa_media(refcursor) returns numeric as 'Declare curs_cod ALIAS FOR $1; V_NOTA numeric(3,1); TOT_NOTA numeric(4,1) :=0; CODDIS HISTORICO.CODIGO%TYPE; CONTADOR INTEGER :=0; MEDIA numeric(4,1);

LOOP fetch curs_cod into CODDIS; EXIT WHEN NOT FOUND; SELECT INTO V_NOTA NOTA FROM HISTORICO WHERE CODIGO='''' CODDIS ''''; IF V_NOTA IS NOT NULL THEN TOT_NOTA:=TOT_NOTA+V_NOTA; CONTADOR:=CONTADOR+1; RAISE NOTICE ''CODDIS: %'', CODDIS; RAISE NOTICE ''V_NOTA: %'', V_NOTA; ELSE RAISE NOTICE ''DISCIPLINA SEM HISTORICO: %'', CODDIS; END IF; MEDIA:=TOT_NOTA/CONTADOR; return (media); END;' Language 'plpgsql'; Create or replace function calc_media_curso(varchar) returns numeric as 'Declare curs REFCURSOR; media numeric(3,2); ESC VARCHAR(20); COD CHAR(5); ESC:='''' $1 ''''; OPEN curs for SELECT codigo from DISCIPLINA where escola =ESC; media := computa_media(curs); close curs; return (media); END;' Language 'plpgsql'; SELECT CALC_MEDIA_CURSO('INFORMATICA'); TRIGGERS Um trigger e uma funcao que é chamada toda vez que um determinado evento acontece. Suponha que se queira armazenar em uma nova tabela, todas as exclusoes e atualizacoes ocorridas na tabela HISTORICO. Para isto, vamos criar a tabela HISTORICO_LOG com todas as colunas da tabela HISTORICO e mais 3 colunas para registrar o usuario, data e operacao (DELETE ou UPDATE) realizada. CREATE TABLE historico_log ( matricula numeric(4,0) NOT NULL, codigo character(5) NOT NULL, nota numeric(3,1),

usuario varchar, data_operacao date, operacao varchar); Vamos então criar uma função TRIGGER que executa sempre que uma mudanca é realizada na tabela HIISTORICO. Uma funcao TRIGGER nao possui argumentos e retorna um tipo de dados especial, o tipo TRIGGER. CREATE FUNCTION REGISTRO() RETURNS TRIGGER As ' Insert into historico_log values (OLD.matricula, OLD.codigo, OLD.nota, CURRENT_USER, Now(), TG_OP); RETURN NULL; END;' Language 'plpgsql'; Funcoes de Trigger tem acesso a varias variaveis pre-definidas que facilitam encontrar informacao sobre ocontexto em que o evento aconteceu. A variavel OLD contem a copia da linha original da tabela HISTORICO no momento em que um trigger é executado para uma operacao de UPDATE ou DELETE. A varivel NEW contem uma copia da nova linha da tabela HISTORICO quando um trigger é executado para uma operacao de INSERT ou UPDATE. Quando o trigger REGISTRO executa, ele cria uma nova linha na tabela HISTORICO _LOG que contem uma copia da linha original da tabela HISTORICO, o nome do usuario que fez a modificacao, a data em que ocorreu e o tipo de operacao. TG_OP recebera UPDATE ou INSERT ou DELETE. O comando CREATE TRIGGER associa uma funcao com um ou mais eventos em uma tabela. O comando abaixo cria o trigger REGISTRA_HISTORICO associado aos eventos de exclusao(delete) ou atualizacao(update) na tabela HISTORICO. CREATE TRIGGER REGISTRA_HISTORICO AFTER DELETE OR UPDATE ON HISTORICO FOR EACH ROW EXECUTE PROCEDURE REGISTRO(); Um comando DELETE ou UPDATE pode afetar varias linhas. A clausula FOR EACH determina se o trigger deve ser executado para cada linha ou para cada todo o comando. Voce pode especificar ROW ou STATEMENT.