93
Capítulo 1: SQL- PSM (Persistent Stored Modules) Banco de Dados II Banco de Dados II Prof. Carlos Eduardo Pires Prof. Carlos Eduardo Pires [email protected] [email protected]

Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires [email protected]

Embed Size (px)

Citation preview

Page 1: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM (Persistent Stored Modules)

Banco de Dados IIBanco de Dados IIProf. Carlos Eduardo PiresProf. Carlos Eduardo Pires

[email protected]@dsc.ufcg.edu.br

Page 2: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 2

Motivação

Ex.: Escreva um programa Pascal que leia a matricula de um empregado e imprima as informações sobre este empregado.program Imprima;

var loop: char; matricula: integer; E: record of

nome: string[15];endereco: string[30];funcao: string[10];salario: real; end;

begin loop := ‘S’; while (loop = ‘S’) do begin writeln(‘Entre com a matricula:’); readln(matricula); $ select nome, endereço, função, salario

into :E.nome, E.endereco, :E.funcao, :E.salario where matricula = :matricula;

writeln(E.nome, :E.endereco, E.funcao, E.salario);writeln(‘Deseja ler mais empregados(S/N)?’);readln(loop);

end;end.

Uma consulta é executada a cada iteração:

E o desempenho?

Page 3: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 3

Cursor

No programa anterior uma única tupla (ou linha) é selecionada pelo SQL embutido

Em geral, uma consulta resulta em várias tuplas Problema

SQL processa um conjunto de tuplas, enquanto que C e Pascal (ou outra linguagem host) processam uma tupla por vez

Solução Introduziu-se o conceito de cursor para permitir

processar uma tupla por vez nas linguagens hospedeiras

Page 4: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 4

Cursor

Problema: “Impedance Mismatch” SQL trabalha com relações Linguagens de programação trabalham de forma

orientada a registro Como fazer para ler os dados de um conjunto

retornado pelo SQL em uma linguagem de programação?

Precisamos ter um mecanismos para associar os valores retornados pelo SGBD em variáveis da aplicação

Faz-se isso usando variáveis hospedeiras

Page 5: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 5

Cursor

Ponteiro para uma única tupla do resultado da consulta (result set)

Cada cursor possui uma consulta associada, especificada como parte da operação que define o cursor

A consulta é executada quando o cursor for aberto

Em uma mesma transação, um cursor pode ser aberto ou fechado qualquer número de vezes

Pode-se ter vários cursores abertos ao mesmo tempo

Page 6: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 6

Cursor

Sintaxe para especificação de um cursorEXEC SQL DECLARE nome-cursor

CURSOR FOR cláusula-select

Um cursor possui as seguintes operações: OPEN

Executa a consulta especificada e põe o cursor para apontar para uma posição anterior à primeira tupla do resultado da consulta

FETCH Move o cursor para apontar para próxima linha no resultado da

consulta, tornando-a a tupla corrente e copiando todos os valores dos atributos para as variáveis da linguagem hospedeira usada

CLOSE Fecha o cursor

Page 7: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 7

OPEN

FETCH

CLOSE

SELECT ename

FROM employee

Banco de DadosKINGSMITHJOHN...

Cursor

KINGSMITHJOHN...

Cursor

KINGSMITHJOHN...

Cursor

Page 8: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 8

Cursor

UPDATE … CURRENT OF: realiza a atualização dos atributos da tupla que está sendo apontada pelo cursor (linha corrente). Sintaxe:UPDATE tabela

SET lista de atribuições

WHERE CURRENT OF cursor

DELETE ... CURRENT OF: elimina a tupla que está sendo apontada pelo cursor (linha corrente). Sintaxe:DELETE

FROM tabela

WHERE CURRENT OF cursor

Page 9: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 9

Um Exemplo de Uso de Cursor em CEXEC SQL BEGIN DECLARE SECTION;

char SQLSTATE[6];char titulo[101];char ano[5];

EXEC SQL DECLARE filme_cursor CURSOR FORSELECT tituloFROM filmesWHERE ano = :ano;

void main () {EXEC SQL WHENEVER SQLERROR GOTO erro;strcpy(ano,”1998”);EXEC SQL OPEN filme_cursor;while (strcmp(SQLSTATE, “02000”) != 0) {

EXEC SQL FETCH filme_cursorINTO :titulo;

printf(“%s\n”, titulo);};EXEC SQL CLOSE filme_cursor;return;erro:

printf(“Um Erro ocorreu!\n”);};

Page 10: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 10

Exemplo Usando DELETE e UPDATE// Se empregado ganha mais de 10000 é demitido; senão tem seu // salário reduzido em 20%

void reducaodeFolhadePagamento() {

EXEC SQL BEGIN DECLARE SECTION;char SQLSTATE[6];float salario;

EXEC SQL END DECLARE SECTION;EXEC SQL DECLARE salCursor CURSOR FOR

SELECT salario FROM Empregado ;EXEC SQL OPEN salCursor;while(1) {

EXEC SQL FETCH FROM salCursor INTO :salario;

// Verifica se não há mais tuplasif (strcmp(SQLSTATE, “02000”)) break;if (salario > 10000)

EXEC SQL DELETE FROM EmpregadoWHERE CURRENT OF salCursor;

else EXEC SQL UPDATE EmpregadoSET salario = salario - salario * 0.2;WHERE CURRENT OF salCursor;

} EXEC SQL CLOSE salCursor;}

Page 11: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 11

Scrolling Cursors

Por default, cursores movem-se do início do result set para frente (forward)

Podemos movê-los também para trás e/ou para qualquer posição no result set

Devemos acrescentar SCROLL na definição do cursor

Exemplo EXEC DECLARE meuCursor SCROLL CURSOR

FOR Empregado;

Page 12: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 12

Scrolling Cursors

Num FETCH, podemos adicionar as seguintes opções: NEXT ou PRIOR: pega o próximo ou anterior FIRST ou LAST: obtém o primeiro ou último RELATIVE seguido de um inteiro: indica quantas

tuplas mover para frente (se positivo) ou para trás (se negativo)

ABSOLUTE seguido de um inteiro: indica a posição da tupla contando do início (se positivo) ou do final (se negativo)

Page 13: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 13

Exercício de Sala

Sem usar a sintaxe de uma linguagem de programação (ou seja, usando o bom e velho português) escrever um código fictício para recuperar e imprimir o nome dos alunos matriculados na turma de BD2, período 2010.2

Page 14: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 14

Motivação

Vimos anteriormente que código SQL pode ser “misturado” com o código de uma linguagem de programação

Porém, é perfeitamente possível separar Código da LP na aplicação Código SQL no BD, nesse caso precisamos dar um

“nome” ao código SQL

O código da LP faz chamadas ao código SQL através desses nomes

Page 15: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 15

Integração Estreita com SGBDs

O uso de SQL/PSM (Stored Procedures) como PL/SQL, SQLJ, TransactSQL,…, são extensões de SQL Processadas no lado servidor da arquitetura cliente-

servidor: muito bom para o desempenho

Page 16: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 16

Stored Procedures (SP)

Em português, procedimentos armazenados Conjuntos de comandos SQL definidos pelo

usuário que ficam armazenados num BD como um procedimento/função para eventuais processamentos

São processamentos de tarefas da aplicação que residem no SGBD ao invés de no código da aplicação (cliente)

Page 17: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 17

Vantagens das Stored Procedures

Desempenho Ex.: Seja a consulta

SELECT codigop, nome FROM Projeto p, Alocacao a WHERE p.codproj = a.codigop

Se vários usuários realizarem esta consulta o tráfego de rede (dados e texto SQL) será alto

Se criarmos uma SP para executar a consulta, os usuários necessitarão apenas de um comando para executar a consulta anterior: EXEC nomeProcedimento;

A consulta anterior seria compilada a cada chamada, enquanto o SP contendo a consulta seria compilado uma única vez

Page 18: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 18

Vantagens das Stored Procedures

Manutenção Facilita o gerenciamento do BD, pois a consulta é

escrita em um único lugar A manutenção torna-se mais eficaz e segura

Segurança Podemos usar SPs para limitar o acesso de alguns

usuários ao BD A maneira em que o BD pode ser modificado é

estritamente definida

Page 19: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 19

Stored Procedures: SQL/PSM

SQL/PSM (Persistent Stored Modules) Parte do padrão SQL relativo às Stored Procedures

Cada SGBD oferece sua própria linguagem (PL/SQL, Transact/SQL, PL/pgSQL, etc.)

Em PSM, definimos módulos que são coleções de definições de funções ou procedimentos, declarações de tabelas temporárias, dentre outros

Page 20: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 20

Stored Procedures: SQL/PSM

Criando Funções e Procedimentos

CREATE PROCEDURE <NOME> (<parâmetros>)declarações locais

corpo do procedimento;

CREATE FUNCTION <NOME> (<parâmetros>) RETURNS <tipo>

declarações locaiscorpo da função;

obs.: parâmetros são do tipo modo-nome-tipo, onde modo indica IN, OUT ou INOUT

Parâmetros em funções devem ter modo IN

Page 21: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 21

Stored Procedures: SQL/PSM

Exemplo

CREATE PROCEDURE MudaEndereco (

IN endAntigo VARCHAR(255),

IN endNovo VARCHAR(255)

)

UPDATE Empregado

SET endereco = endNovo

WHERE endereco = endAntigo;

Page 22: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 22

Stored Procedures: SQL/PSM

Alguns comandos 1) Chamada a um procedimento:

CALL <nome procedure> (<lista argumentos>); Obs.: CALL é aplicado apenas a Procedures (não a

Function) Esta chamada pode ser realizada de vários lugares:

Programa com SQL embutido EXEC SQL CALL calcula(:x, 3);

Como comando em outro procedimento ou função PSM: CALL calcula (10);

2) Comando de Retorno (usado apenas em funções) RETURN <expressão>; Obs.: este comando não encerra a função

Page 23: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 23

Stored Procedures: SQL/PSM

3) Declaração de variáveis locais:

DECLARE <nome> <tipo>; 4) Comando de atribuição

SET <variável> = <expressão>; 5) Grupo de comandos:

delimitados por BEGIN e END 6) Label

Colocamos labels em comandos precedendo estes pelo nome do label e dois pontos

Page 24: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 24

Stored Procedures: SQL/PSM

7) Comandos condicionais

IF <condição> THEN

<comandos>

ELSEIF <condição> THEN

<comandos> …

ELSE <comandos>

END IF; 8) Laços

LOOP

<Comandos>

END;

Page 25: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 25

Stored Procedures: SQL/PSM Exemplo: função que recebe um ano e nome de estúdio

e retorna TRUE se não produziu nenhum filme naquele ano ou se aquele estúdio produziu apenas um filme preto e branco

CREATE FUNCTION PretoeBranco (p_ano int, studio char[15]) RETURNS BOOLEANIF NOT EXISTS (SELECT *

FROM Filme WHERE ano = p_ano AND nomeStudio = studio) THENRETURN TRUE;

ELSEIF 1 = (SELECT COUNT(*) FROM Filme

WHERE ano = p_ano AND nomeStudio = studio AND NOT emcores) THENRETURN TRUE;

ELSERETURN FALSE;

END IF;

Page 26: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 26

Stored Procedures: SQL/PSMExemplo: Procedimento que calcula a duração média dos filmes de um estúdio

CREATE PROCEDURE MeanVar (IN s char[15], OUT mean REAL)DECLARE NotFound FOR SQLSTATE ‘02000’;DECLARE filmeCursor CURSOR FOR

select duracaofrom Filmewhere nomeStudio = s;

DECLARE novaDuracao INTEGER;DECLARE contaFilmes INTEGER;BEGIN

SET mean = 0.0;SET contaFilmes = 0;OPEN filmeCursor;filmeLOOP: LOOP

FETCH filmeCursor INTO novaDuracao;IF NotFound THEN

LEAVE filmeLOOPEND IF;SET contaFilmes = contaFilmes + 1;SET mean = mean + novaDuracao;

END LOOP;SET mean = mean / contaFilmes;CLOSE filmeCursor;

END;

Page 27: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 27

Laços em PSM

Laços FORFOR <nome laço> AS <nome cursor> CURSOR FOR

<query>

DO<comandos>

END FOR;

ExemploFOR alunoLOOP AS alunoCursor CURSOR FOR

SELECT nome, idade FROM Aluno WHERE periodo = ‘2010.2’;

DO

...

END FOR;

Page 28: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 28

Exemplo do Laço FOR

Exemplo: Mesmo procedimento anterior, usando Laço FOR

CREATE PROCEDURE MeanVar (IN s char[15], OUT mean REAL)

DECLARE contaFilmes INTEGER;

BEGIN

SET mean = 0.0;

SET contaFilmes = 0;

FOR filmeLOOP AS filmeCursor CURSOR FOR

SELECT duracao FROM Filme WHERE nomeStudio = s;

DO

SET contaFilmes = contaFilmes + 1;

SET mean = mean + duracao;

END FOR;

SET mean = mean / contaFilmes;

END;

Obs.: veja que não precisa de OPEN, FETCH e CLOSE do cursor

Page 29: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 29

Outros Tipos de Laços em PSM

Laço WHILEWHILE <condição> DO

<comandos>

END WHILE;

REPEATREPEAT

<comandos>

UNTIL <condição>

END REPEAT;

Page 30: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 30

Exceções em PSM

É possível testar o SQLSTATE para verificar a ocorrência de erros e tomar uma decisão, quando erros ocorram

Isto é feito através do EXCEPTION HANDLER que é associado a blocos BEGIN END (o handler aparece dentro do bloco)

Os componentes do handler são:1) Lista de exceções a serem tratadas2) Código a ser executado quando exceção ocorrer3) Indicação para onde ir depois que o handler concluir

SINTAXE: DECLARE <onde ir> HANDLER FOR <condições><comando>

As escolhas de <onde ir> são: CONTINUE EXIT (sai do bloco BEGIN .. END) UNDO

Page 31: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 31

Exemplo de Exceções em PSM

CREATE FUNCTION getSalario (mat integer) RETURNS FLOAT

DECLARE NotFound CONDITION FOR SQLSTATE ‘02000’; DECLARE TooMany CONDITION FOR SQLSTATE ‘21000’;BEGIN

DECLARE EXIT HANDLER FOR NotFound, TooManyRETURN NULL;

RETURN (SELECT salario FROM Empregado WHERE matricula = mat);

END;

TooMany muitas linhas retornadas pelo SELECT NotFound nenhuma linha retornada pelo SELECT

Page 32: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 32

PL/SQL – Oracle Stored Procedures

Linguagem de desenvolvimento do SGBD Oracle que “implementa” SQL/PSM (não é fiel ao padrão)

Significa “Procedural Language extensions to SQL” Permite variáveis locais, laços, condições, procedures,

consulta à relações “one tuple at a time”, etc Forma geral

DECLAREdeclarações (optativo)

BEGINcomandos executáveis; (obrigatórios)

EXCEPTIONcomandos para manipular erros (optativo)

END;

Page 33: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 33

Oracle Stored Procedures

Código PL/SQL é feito de blocos com uma única estrutura

Existem dois tipos de blocos em PL/SQL:1. Blocos Anônimos: não possuem nomes (são como

scripts) Podem ser escritos e executados imediatamente no iSQL*Plus Podem ser usados em um trigger (gatilho)

2. Blocos Nomeados: são armazenados no banco de dados Procedures Functions Pacotes

Page 34: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 34

Blocos Anônimos

DECLARE (opcional)/* aqui se declaram as variáveis que serão usadas no bloco */

BEGIN (obrigatório)/* define-se os comandos que dizem o que o bloco faz*/

EXCEPTION (opcional)/* define-se as ações que acontecem se uma exceção for lançado

durante a execução deste bloco */

END; (obrigatório)/

Page 35: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 35

DECLARE

Sintaxe

Exemplos

identifier [CONSTANT] datatype [NOT NULL]

[:= | DEFAULT expr];

identifier [CONSTANT] datatype [NOT NULL]

[:= | DEFAULT expr];

DECLARE birthday DATE; age NUMBER(2) NOT NULL := 27; name VARCHAR2(13) := 'Levi'; magic CONSTANT NUMBER := 77; valid BOOLEAN NOT NULL := TRUE;

DECLARE birthday DATE; age NUMBER(2) NOT NULL := 27; name VARCHAR2(13) := 'Levi'; magic CONSTANT NUMBER := 77; valid BOOLEAN NOT NULL := TRUE;

Note que PL/SQL inclui todos tipos SQL, e outros mais…

Page 36: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 36

Declarando Variáveis com %TYPE

Exemplos

DECLARE sname sailors.sname%TYPE; fav_boat VARCHAR2(30); my_fav_boat fav_boat%TYPE := ‘GrafSpee';...

Acessando coluna sname na tabela Sailors

Acessando outra variável

Page 37: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 37

Criando um PL/SQL Record (Registro)

Um record é um tipo de variável que podemos definir (como ‘struct’ em C ou ‘object’ em Java)

DECLARE TYPE sailor_record_type IS RECORD (sname VARCHAR2(10), sid VARCHAR2(9), age NUMBER(3),

rating NUMBER(3)); sailor_record sailor_record_type;...BEGIN sailor_record.sname:=‘peter’; sailor_record.age:=45;…

DECLARE TYPE sailor_record_type IS RECORD (sname VARCHAR2(10), sid VARCHAR2(9), age NUMBER(3),

rating NUMBER(3)); sailor_record sailor_record_type;...BEGIN sailor_record.sname:=‘peter’; sailor_record.age:=45;…

Page 38: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 38

Oracle Stored Procedures

São objetos armazenados no BD que usam comandos PL/SQL e SQL em seus corpos

SintaxeCREATE OR REPLACE PROCEDURE

<nome> (<lista_argumentos>)

AS / IS

<declarações>

BEGIN

<comandos PL/SQL e SQL>

END;

Atenção:

AS ou IS substituem o DECLARE

Page 39: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 39

Oracle Stored Procedures

<Lista_argumentos> tem triplas nome-modo-tipo. Modo: IN, OUT ou IN OUT para read-only, write-only,

read/write, respectivamente. Tipos de Dados

Padrão SQL + tipos genéricos como NUMBER = qualquer tipo inteiro ou real

Como tipos nas procedures devem casar com tipos no esquema do BD, pode-se usar uma expressão da forma

tabela.campo%TYPEpara capturar o tipo corretamente

Page 40: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 40

Exemplo de Oracle Stored Procedure

Uma procedure que inclui uma nova cerveja e seu preço no menu do bar AlviRubro

Vende (bar, cerveja, preço)

CREATE OR REPLACE PROCEDURE MenuAlviRubro (p_cerva IN Vende.cerveja%TYPE,p_preco IN Vende.preço%TYPE)

ASBEGIN

INSERT INTO Vende VALUES(‘AlviRubro’, p_cerva, p_preco);COMMIT;

END;/

Page 41: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 41

Executando Stored Procedures

Uma chamada a uma procedure pode aparecer no corpo de um comando PL/SQLBEGIN

MenuAlviRubro('AlviRubro','Bud', 2.50);

MenuAlviRubro('AlviRubro','Carlsberg', 5.00);

END;

Uma chamada a uma procedure pode aparecer no prompt da ferramenta (iSQL*Plus) EXEC(UTE) MenuAlviRubro ('AlviRubro','Sol', 1.15);

Page 42: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 42

Um Segundo ExemploCREATE OR REPLACE PROCEDURE p1 (p_empid IN NUMBER, p_sal OUT NUMBER)ISBEGIN SELECT salary INTO p_sal FROM employees WHERE employee_id = p_empid;END;/

CREATE OR REPLACE PROCEDURE p2IS v_sal NUMBER; v_empid NUMBER := 101;BEGIN p1(v_empid,v_sal); DBMS_OUTPUT.PUT_LINE('O empregado '||TO_CHAR(v_empid)||' recebe '||TO_CHAR(v_sal));END;/

SQL> SET SERVEROUTPUT ONSQL> EXECUTE p2O empregado 101 recebe 17000

Atenção:

Não é necessário informar o tamanho dos parâmetros

Page 43: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 43

Oracle Stored Procedure

Atribuição de valores a variáveis é denotada por := Desvio

IF <condição> THEN <comando(s)>

ELSIF <condição> THEN<comandos(s)>

ELSE <comando(s)>

END IF; Laço

LOOP. . .

EXIT WHEN <condição>. . .

END LOOP;

Page 44: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 44

Consultas em PL/SQL

Single-row selects permitem atribuir a uma variável o resultado de uma consulta que produz uma única tupla

Um select-from-where em PL/SQL deve ter uma cláusula INTO listando as variáveis que recebem os resultados da consulta

Ocorre erro se o select-from-where retornar mais de uma tupla; neste caso, é preciso usar um cursor

Ocorre erro também se o select-from-where retornar zero tupla

Page 45: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 45

Single-Row SELECT

Exemplo: Encontrar o preço da cerveja Schincariol no bar AlviRubro Vende(bar, cerveja, preço)

DECLARE

p Vende.preço %TYPE;

BEGIN

SELECT preço

INTO p

FROM Vende

WHERE bar = ‘AlviRubro’

AND cerveja = ‘Schincariol’;

END;

Page 46: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 46

Cursores

DeclaraçãoCURSOR <nome> IS

comando select-from-where O cursor aponta para cada tupla por vez da relação-

resultado da consulta select-from-where, usando um fetch statement dentro de um laço. Fetch statement:

FETCH <nome_cursor> INTOlista_variáveis;

Um laço é interrompido por: EXIT WHEN <nome_cursor>%NOTFOUND; O valor é TRUE se não houver mais tupla a apontar

OPEN e CLOSE abrem e fecham um cursor

Page 47: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 47

Criando um Cursor

Exemplo

DECLARE

CURSOR c IS SELECT name, salary FROM customer;

v_name customer.name%TYPE;

v_salary customer.salary%TYPE;

BEGIN

open c;

fetch c into v_name, v_salary;

Page 48: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 48

Exemplo

DECLARE pi constant NUMBER(8,7) := 3.1415926; area NUMBER(14,2); CURSOR rad_cursor IS SELECT * FROM rad_vals; rad_value rad_cursor%ROWTYPE;

BEGIN OPEN rad_cursor; LOOP

FETCH rad_cursor INTO rad_value; EXIT WHEN rad_cursor%NOTFOUND; area := pi * power(rad_value.radius,2); INSERT INTO areas VALUES

(rad_value.radius, area); END LOOP; CLOSE rad_cursor; COMMIT;END;

DECLARE pi constant NUMBER(8,7) := 3.1415926; area NUMBER(14,2); CURSOR rad_cursor IS SELECT * FROM rad_vals; rad_value rad_cursor%ROWTYPE;

BEGIN OPEN rad_cursor; LOOP

FETCH rad_cursor INTO rad_value; EXIT WHEN rad_cursor%NOTFOUND; area := pi * power(rad_value.radius,2); INSERT INTO areas VALUES

(rad_value.radius, area); END LOOP; CLOSE rad_cursor; COMMIT;END;

radius

3

6

8

Rad_cursor

Fetch

Rad_val

Radius AreaAREAS

3 28.27

RAD_VALS

68

113.1201.06

O código completo do exemplo está disponível no Google Groups

Page 49: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 49

Atributos Explícitos de Cursor

Obtém informação de status sobre um cursor

Atributo Tipo Descrição

%ISOPEN Boolean Retorna TRUE se o cursor estiver aberto

%NOTFOUND Boolean Retorna TRUE se o fetch mais recente não retorna uma tupla

%FOUND Boolean Retorna TRUE se o fetch mais recente retorna uma tupla (complemento de %NOTFOUND)

%ROWCOUNT Number Retorna o total de tuplas acessadas até o momento

Page 50: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 50

Exemplo

Uma procedure que examina o menu do bar AlviRubro e aumenta em 1.00 todos os preços que são menores que 3.00 Vende(bar, cerveja, preço)

Um simples UPDATE poderia resolver esse problema, mas mudanças mais complicadas podiam exigir uma procedure

Page 51: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 51

ExemploCREATE PROCEDURE Aumento AS

aCerveja Vende.cerveja%TYPE;oPreço Vende.preço%TYPE;CURSOR c IS

SELECT cerveja, preçoFROM VendeWHERE bar =`AlviRubro´;

BEGINOPEN c;LOOP

FETCH c INTO aCerveja, oPreço;EXIT WHEN c%NOTFOUND;IF oPreço < 3.00 THEN

UDPATE VendeSET preço = oPreço + 1.00WHERE bar = `AlviRubro´AND cerveja = aCerveja;

END IF;END LOOP;CLOSE c;

END;

Page 52: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 52

Tipo %ROWTYPE

Qualquer estrutura (e.g. cursores e nomes de tabela) que tem um tipo tupla pode ter seu tipo capturado com %ROWTYPE

Pode-se criar variáveis temporárias tipo tupla e acessar seus componentes como variável.componente (“dot notation”)

Muito útil, principalmente se a tupla tem muitos componentes

Page 53: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 53

Declarando Variáveis com %ROWTYPE

Declare uma variável (registro) com o tipo de uma linha de uma tabela.

E como acessar os campos de reserves_record?

reserves_record Reserves%ROWTYPE;

reserves_record.sid:=9;

Reserves_record.bid:=877;

Tabela Reserves

Page 54: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 54

ExemploA mesma procedure com a variável tupla cp.

CREATE PROCEDURE Aumento ASCURSOR c IS

SELECT cerveja, preçoFROM VendeWHERE bar = `AlviRubro´;

cp c%ROWTYPE;BEGIN

OPEN c;LOOP

FETCH c INTO cp;EXIT WHEN c%NOTFOUND;IF cp.preço < 3.00 THEN

UDPATE VendeSET preço= cp.preço + 1.00WHERE bar = `AlviRubro´AND cerveja = cp.cerveja;

END IF;END LOOP;CLOSE c;

END;

Page 55: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 55

Funções

Podemos definir uma função:

CREATE FUNCTION <name> (<param_list>)

RETURN <return_type>

AS ... No corpo da função, "RETURN <expression>;"

sai (retorna) da função e retorna o valor de <expression>

Page 56: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 56

ExemploCREATE OR REPLACE FUNCTION func01 (valor IN NUMBER)RETURN VARCHAR2ASBEGIN IF valor IN (0,1) THEN RETURN('if'); ELSIF valor IN (1,2,3) THEN RETURN('elsif'); ELSE RETURN('else'); END IF; DBMS_OUTPUT.PUT_LINE('Fui até o fim'); RETURN('Fim');END;/

SET SERVEROUTPUT ON/* Para testar com outros valores, basta substituir o parâmetro passado na função func01 */

DECLARE texto VARCHAR2(1000);BEGIN texto := func01(2); DBMS_OUTPUT.PUT_LINE(texto);END;/

Page 57: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 57

Dica

Para descobrir quais procedures e functions você já criou:

SELECT object_type, object_name, status

FROM user_objects

WHERE object_type IN ('PROCEDURE','FUNCTION');

Page 58: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 58

Removendo Procedures e Funções

Para remover uma stored procedure/function:

DROP PROCEDURE <procedure_name>;

DROP FUNCTION <function_name>;

Page 59: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 59

Outras Formas de Laços

Comando FOR Permite que uma determinada sequência de

comandos seja executada n vezes

SintaxeFOR contador IN [REVERSE] valorInicial..valorFinal

LOOP

sequência de comandos

END LOOP

Page 60: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 60

Exemplo de Comando FORCREATE OR REPLACE PROCEDURE VerificaEstoqueAS

codInicial Produto.codProduto%Type;codFinal CodInicial%Type;v_estoque Produto.estoque%Type;

BEGINSELECT Min(CodProduto), Max(codProduto)INTO codInicial, codFinalFROM Produto;

FOR contador IN codInicial..codFinal LOOPSELECT estoqueINTO v_estoqueFROM produto WHERE codProduto = contador AND estoque > 0;

DBMS_OUTPUT.PUT_LINE ('O código '|| contador || ' tem em estoque' ||

v_estoque);END LOOP;

END;

Pergunta:

E se houverem “brechas” em codProduto?

Exemplo: 1, 2, 4...

Page 61: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 61

Exemplo de Cursor FOR

CREATE OR REPLACE PROCEDURE p10 ISBEGIN

FOR emp_rec IN (SELECT last_name, salaryFROM employeesWHERE salary >= 10000)

LOOP

DBMS_OUTPUT.PUT_LINE ('O empregado '||emp_rec.last_name||' ganha '||emp_rec.salary||' dólares por mês');

END LOOP;

END;/

SET SERVEROUTPUT ONEXEC p10

Page 62: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 62

Outras Formas de Laços

Comando WHILEWHILE condição LOOP

ComandosEND LOOP;

ExemploDECLARE

TEN number:=10;i number_table.num%TYPE:=1;

BEGIN WHILE i <= TEN LOOP INSERT INTO number_table VALUES (i); i := i + 1; END LOOP;END;

Page 63: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 63

Exercício

Criar uma função (calc_sal_total) que calcule o salário total de um empregado (salário fixo + comissão). A função deve receber dois valores numéricos e devolver um valor numérico.

Criar uma procedure (update_sal) que atualize o salário total de todos os empregados usando a função calc_sal_total. Um cursor deve ser usado dentro da procedure

Tabela Empregado (id, nome, salário, comissão, sal_total)

Page 64: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 64

Pacotes

São objetos que agrupam logicamente elementos de programação PL/SQL Tipos definidos pelo usuário, variáveis, exceções

PL/SQL, cursores, procedures e funções

Um pacote possui duas partes: Especificação Corpo

Page 65: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 65

Exemplo de Pacote

CREATE OR REPLACE PACKAGE pck_emp

IS

PROCEDURE query_emp

(in_employee_id employees.employee_id%TYPE,

out_name OUT employees.first_name%TYPE,

out_salary OUT employees.salary%TYPE,

out_phone_number OUT employees.phone_number%TYPE);

END pck_emp;

/

Page 66: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 66

Exemplo de Pacote

CREATE OR REPLACE PACKAGE BODY pck_empIS

PROCEDURE query_emp(in_employee_id employees.employee_id%TYPE,out_name OUT employees.first_name%TYPE,out_salary OUT employees.salary%TYPE,out_phone_number OUT employees.phone_number%TYPE)ISBEGIN SELECT first_name, salary , phone_number INTO out_name, out_salary, out_phone_number FROM employees WHERE employee_id = in_employee_id; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Empregado '||in_employee_id||' não existe'); END query_emp;

END pck_emp;/

Page 67: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 67

Exemplo de Pacote

DECLAREaEmployee_id employees.employee_id%TYPE:=206;aFirst_name employees.first_name%TYPE;aSalary employees.salary%TYPE;aPhone_number employees.phone_number%TYPE;

BEGIN

pck_emp.query_emp(aEmployee_id,aFirst_name,aSalary,aPhone_number);DBMS_OUTPUT.PUT_LINE('aFirst_name --> '||aFirst_name);DBMS_OUTPUT.PUT_LINE('aSalary --> '||aSalary);DBMS_OUTPUT.PUT_LINE('aPhone_number --> '||aPhone_number);

END;/

Page 68: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 68

Trigger (Gatilho)

Trecho de código armazenado executado implicitamente quando ocorre um certo evento

Criados para executar operações relacionadas

Não devem ser criados quando já existirem funcionalidades que já façam o trabalho

Page 69: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 69

Exemplo de Trigger

Page 70: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 70

Criando Triggers

Instante de Execução Tabela: BEFORE, AFTER Visão: INSTEAD OF

Evento: INSERT, UPDATE ou DELETE Objeto associado: tabela ou visão Tipo: linha ou sentença Cláusula WHEN: condição de restrição Corpo do trigger: bloco contendo comandos

Page 71: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 71

Sequência de Disparo

DEPTNO10203040

DNAMEACCOUNTINGRESEARCHSALESOPERATIONS

LOCNEW YORKDALLASCHICAGOBOSTON

• Ação do TriggerAção do TriggerBEFORE statement triggerBEFORE statement trigger

BEFORE row triggerBEFORE row triggerAFTER row triggerAFTER row trigger

AFTER statement triggerAFTER statement trigger

SQL> INSERT INTO dept (deptno, dname, loc) 2 VALUES (50, 'EDUCATION', 'NEW YORK');

SQL> INSERT INTO dept (deptno, dname, loc) 2 VALUES (50, 'EDUCATION', 'NEW YORK');

• Comando DMLComando DML

Sequência de disparo de um trigger em uma tabela quando apenas uma linha é manipulada

Page 72: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 72

Sequência de Disparo

EMPNO

7839

7698

7788

ENAME

KING

BLAKE

SMITH

DEPTNO

30

30

30

BEFORE statement triggerBEFORE statement trigger

BEFORE row triggerBEFORE row triggerAFTER row triggerAFTER row triggerBEFORE row triggerBEFORE row triggerAFTER row triggerAFTER row triggerBEFORE row triggerBEFORE row triggerAFTER row triggerAFTER row trigger

AFTER statement triggerAFTER statement trigger

SQL> UPDATE emp 2 SET sal = sal * 1.1 3 WHERE deptno = 30;

SQL> UPDATE emp 2 SET sal = sal * 1.1 3 WHERE deptno = 30;

Sequência de disparo de um trigger em uma tabela quando muitas linhas são manipuladas

Page 73: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 73

Criando um Statement Trigger

SQL> CREATE OR REPLACE TRIGGER secure_emp

2 BEFORE INSERT ON emp

3 BEGIN

4 IF (TO_CHAR (sysdate,'DY') IN ('SAT','SUN')) OR

5 (TO_CHAR(sysdate,'HH24') NOT BETWEEN

6 '08' AND '18')

7 THEN RAISE_APPLICATION_ERROR (-20500,

8 'You may only insert into EMP during normal hours.');

9 END IF;

10 END;

11 /

SQL> CREATE OR REPLACE TRIGGER secure_emp

2 BEFORE INSERT ON emp

3 BEGIN

4 IF (TO_CHAR (sysdate,'DY') IN ('SAT','SUN')) OR

5 (TO_CHAR(sysdate,'HH24') NOT BETWEEN

6 '08' AND '18')

7 THEN RAISE_APPLICATION_ERROR (-20500,

8 'You may only insert into EMP during normal hours.');

9 END IF;

10 END;

11 /

Page 74: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 74

Testando o Trigger secure_emp

SQL> INSERT INTO emp (empno, ename, deptno)

2 VALUES (7777, 'BAUWENS', 40);

INSERT INTO emp (empno, ename, deptno)

*

ERROR at line 1:

ORA-20500: You may only insert into EMP during normal hours.

ORA-06512: at "A_USER.SECURE_EMP", line 4

ORA-04088: error during execution of trigger

'A_USER.SECURE_EMP'

SQL> INSERT INTO emp (empno, ename, deptno)

2 VALUES (7777, 'BAUWENS', 40);

INSERT INTO emp (empno, ename, deptno)

*

ERROR at line 1:

ORA-20500: You may only insert into EMP during normal hours.

ORA-06512: at "A_USER.SECURE_EMP", line 4

ORA-04088: error during execution of trigger

'A_USER.SECURE_EMP'

Page 75: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 75

Usando Predicados de Condição

CREATE OR REPLACE TRIGGER secure_empBEFORE INSERT OR UPDATE OR DELETE ON empBEGIN IF (TO_CHAR (sysdate,'DY') IN ('SAT','SUN')) OR (TO_CHAR (sysdate, 'HH24') NOT BETWEEN '08' AND '18') THEN IF DELETING THEN RAISE_APPLICATION_ERROR (-20502, 'You may only delete from EMP during normal hours.'); ELSIF INSERTING THEN RAISE_APPLICATION_ERROR (-20500, 'You may only insert into EMP during normal hours.'); ELSIF UPDATING ('SAL') THEN RAISE_APPLICATION_ERROR (-20503, 'You may only update SAL during normal hours.'); ELSE RAISE_APPLICATION_ERROR (-20504, 'You may only update EMP during normal hours.'); END IF; END IF;END;

Page 76: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 76

Criando Row Triggers

SQL> CREATE OR REPLACE TRIGGER DERIVE_COMMISSION_PCT

2 BEFORE INSERT OR UPDATE OF sal ON emp

3 FOR EACH ROW

4 BEGIN

5 IF NOT (:NEW.JOB IN ('MANAGER' , 'PRESIDENT'))

6 AND :NEW.SAL > 5000

7 THEN

8 RAISE_APPLICATION_ERROR

9 (-20202, 'EMPLOYEE CANNOT EARN THIS AMOUNT');

10 END IF;

11 END;

Page 77: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 77

Usando Qualificadores OLD e NEW

SQL>CREATE OR REPLACE TRIGGER audit_emp_values

2 AFTER DELETE OR INSERT OR UPDATE ON emp

3 FOR EACH ROW

4 BEGIN

5 INSERT INTO audit_emp_table (user_name,

6 timestamp, id, old_last_name, new_last_name,

7 old_title, new_title, old_salary, new_salary)

8 VALUES (USER, SYSDATE, :OLD.empno, :OLD.ename,

9 :NEW.ename, :OLD.job, :NEW.job,

10 :OLD.sal, :NEW.sal );

11 END;

12 /

Page 78: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 78

Tabela audit_emp_values

USER_NAME

EGRAVINA

NGREENBE

TIMESTAMP

12-NOV-97

10-DEC-97

ID

NULL

7844

OLD_LAST_NAME

NULL

MAGEE

NEW_LAST_NAME

HUTTON

TURNER

OLD_TITLE

NULL

CLERK

NEW_TITLE

ANALYST

SALESMAN

NEW_SALARY

3500

1100

Continuação

OLD_SALARY

NULL

1100

INSERTUPDATE

Page 79: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 79

Trigger INSTEAD OF

AplicaçãoAplicação

SQL> INSERT INTO my_view 2 . . .;

SQL> INSERT INTO my_view 2 . . .;

MY_VIEWMY_VIEW

INSTEAD OF INSTEAD OF TriggerTrigger

INSERT INSERT TABLE1TABLE1

UPDATE UPDATE TABLE2TABLE2

Page 80: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 80

Trigger INSTEAD OF

EMPNO7836778279347566

ENAMEKINGCLARKMILLERJONES

SAL5000245013002975

DEPTNO10101020

DNAMENEW YORKNEW YORKNEW YORKDALLAS

TOT_DEPT_SAL87508750875010875

INSERT INTO EMP_DETAILS (EMPNO, ENAME, SAL, DEPTNO)VALUES (9001,'ABBOTT',1000,10)

INSERT INTO EMP_DETAILS (EMPNO, ENAME, SAL, DEPTNO)VALUES (9001,'ABBOTT',1000,10)

INSTEAD OFINSTEAD OFINSERT into INSERT into EMP_DETAILSEMP_DETAILS

INSERT intoINSERT intoEMPLOYEESEMPLOYEES

EMPNO7939769877829001

ENAMEKINGBLAKECLARKABBOTT

SAL5000285024501000

DEPTNO102030

DNAMEACCOUNTINGRESEARCHSALES

TOT_DEPT_SAL9750108759400

UPDATEUPDATEDEPARTMENTSDEPARTMENTS

Page 81: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 81

Exemplo

CREATE VIEW myview ASSELECT e.EMPLOYEE_ID, e.LAST_NAME, e.EMAIL,

e.HIRE_DATE, e.JOB_ID, d.DEPARTMENT_ID, d.DEPARTMENT_NAMEFROM employees e, departments dWHERE e.department_id = d.department_id/

CREATE OR REPLACE TRIGGER myview_trig INSTEAD OF INSERT ON myviewFOR EACH ROW BEGIN

INSERT INTO departments (department_id, department_name) VALUES(:NEW.department_id, :NEW.department_name);

INSERT INTO employees (EMPLOYEE_ID, LAST_NAME, EMAIL, HIRE_DATE, JOB_ID) VALUES(:new.EMPLOYEE_ID, :new.LAST_NAME, :new.EMAIL, :new.HIRE_DATE, :new.JOB_ID);

END;/

INSERT INTO myview VALUES (11,'SILVA','silva@...',sysdate,'AD_PRES',55,'FAZNADA');

select * from departments where department_id = 55; select * from employees where employee_id = 11;

Page 82: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 82

Manipulando Exceções

Exceções são todos os erros e imprevistos que podem ocorrer durante a execução de um bloco PL/SQL

Quando uma exceção ocorre, o SGBD Oracle aborta a execução e procura a área de exceções (EXCEPTION) para tratar a falha

As exceções podem ser Pré-definidas Definidas pelo usuário

Page 83: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 83

Manipulando Exceções

Sintaxe

EXCEPTION

WHEN nomeExceção1 THEN

Comandos;

WHEN nomeExceção2 THEN

Comandos;

WHEN others THEN

Comandos;

Page 84: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 84

Manipulando Exceções

Exemplo

CREATE TABLE pais (id NUMBER PRIMARY KEY, nome VARCHAR2(20));

SET SERVEROUTPUT ON

BEGININSERT INTO pais VALUES (100, 'Brasil');COMMIT;DBMS_OUTPUT.PUT_LINE('Inserção realizada com sucesso');

EXCEPTIONWHEN dup_val_on_index THEN DBMS_OUTPUT.PUT_LINE('País já cadastrado! ');WHEN others THEN DBMS_OUTPUT.PUT_LINE('Erro ao cadastrar país');

END;

Page 85: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 85

Exceções Pré-definidas

Cursor_Already_Open DUP_Val_On_INDEX INVALID_CURSOR Invalid_Number Login_Denied No_Data_Found Not_Logged_On RowType_Mismatch Storage_Error Too_Many_Rows Value_Error Zero_Divide Others

Page 86: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 86

Exceção Definida pelo Usuário

Devem ser declaradas na área de declarações de um bloco ou procedure/function ou package

Comando:Declare

nomeExceção EXCEPTION;Begin

Seqüência de comandosIf … then

RAISE nomeExceção;End If;Comandos

ExceptionWhen NomeExceção then Comandos

End

Page 87: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 87

Exceção Definida pelo Usuário

Exemplo

DECLARE out_of_stock EXCEPTION;number_on_hand NUMBER(4);

BEGIN...IF number_on_hand < 1 THEN

RAISE out_of_stock;END IF;

EXCEPTIONWHEN out_of_stock THEN

-- handle the errorEND;

Page 88: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 88

Quando se cria uma procedure, se houver erros na sua definição, estes não serão mostrados

Para ver os erros de procedure chamada myProcedure, digite: SHOW ERRORS PROCEDURE myProcedure

no iSQLPLUS prompt Para funções, digite:

SHOW ERRORS FUNCTION myFunction

Visualizando Erros na Criação de uma Procedure/Function

Page 89: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 89

Exemplo

CREATE OR REPLACE PROCEDURE proc10

IS

DECLARE

contador NUMBER;

BEGIN

contador := 10

END;

/

SQL> sho err procedure proc10

Falta ponto-e-vírgula

Page 90: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 90

table1index1

view1proc1

func1

seq1

user01table1index1

view1proc1

func1

seq1

user02table1index1

view1proc1

func1

seq1

user03

Oracle Database

user01’s schema

user03’s schema

user02’s schema

Page 91: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 91

Exemplo de Stored Procedure no SGBD SQL Server

1. CREATE PROCEDURE DBO.MostraEmpregadosDep @nomeDep varchar(50) = ‘Pessoal’ - - Dep Default AS SELECT e.mat, e.nome, e.endereco, e.salario FROM Empregados e, Departamento d WHERE d.nomeD = @nomeDep

Uma chamada a este procedimento seria:

USE Empresa -- BB Empresa EXEC MostraEmpregadosDep ‘Informatica’

Page 92: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 92

Java Stored Procedure no SGBD Oracle

import java.sql.*;import java.io.*;import oracle.jdbc.*;public class BookDML { public static void insertBook (String title, String publisher)

throws SQLException {String sql = “INSERT INTO Livros VALUES (?, ?)”;try { Connection con =

DriverManager.getConnection(“jdbc:default:connection:”); PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, title); pstmt.setString(2, publisher); pstmt.close();} catch (SQLException e) { system.err.println(e.getMessage());}

}

Page 93: Capítulo 1: SQL-PSM (Persistent Stored Modules) Banco de Dados II Prof. Carlos Eduardo Pires cesp@dsc.ufcg.edu.br

Capítulo 1: SQL-PSM 93

Java Stored Procedure no SGBD Oracle

Carregando a Classe no Banco de dados:

> loadjava –user baptista BookDML.java

Acessando a classe:

CREATE OR REPLACE PROCEDURE InsertBookJava (title VARCHAR, publisher VARCHAR) AS

Language javaName 'BookDML.insertBook(java.lang.String, java.lang.String)';

Executando do SQL*Plus:

CALL insertBookJava('Meulivro', 'LMV');

Usuário do BD Oracle