74
Banco de Dados II Capítulo 1: SQL-PSM UFCG/DSC Bacharelado em Ciência da Computação Cláudio Baptista, Ph.D.

Banco de Dados II Capítulo 1: SQL-PSM

Embed Size (px)

DESCRIPTION

Banco de Dados II Capítulo 1: SQL-PSM. UFCG/DSC Bacharelado em Ciência da Computação Cláudio Baptista, Ph.D. 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; - PowerPoint PPT Presentation

Citation preview

Page 1: Banco de Dados II Capítulo 1: SQL-PSM

Banco de Dados IICapítulo 1: SQL-PSM

UFCG/DSCBacharelado em Ciência da Computação

Cláudio Baptista, Ph.D.

Page 2: Banco de Dados II Capítulo 1: SQL-PSM

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.

Page 3: Banco de Dados II Capítulo 1: SQL-PSM

Cursor

No programa anterior uma única tupla é selecionada pelo SQL embutido. Geralmente, uma query resulta em várias tuplas.

Problema: SQL processa um conjunto de tuplas, enquanto que C e Pascal (ou outra linguagem host) processa um registro por vez.

Solução: Introduziu-se o conceito de cursor para permitir processar uma tupla por vez nas linguagens hospedeiras.

Page 4: Banco de Dados II Capítulo 1: SQL-PSM

Cursores Problema: “Impedance Mismatch”

SQL trabalha com relações Linguagens de programação trabalham orientada a

registro Como fazer para ler os dados de um conjunto

retornado pelo SQL numa 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: Banco de Dados II Capítulo 1: SQL-PSM

Cursor

Um cursor pode ser visto como um ponteiro que aponta para uma única tupla(linha) do resultado da query.

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

A pesquisa é executada quando o cursor for aberto. Numa 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: Banco de Dados II Capítulo 1: SQL-PSM

Cursor

Sintaxe da especificação de um cursor: EXEC SQL DECLARE nome-cursor CURSOR FOR cláusula-select

Um cursor possui as seguintes operações:- OPEN: executa a query especificada e pões o cursos para

apontar para uma posição anterior a 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: Banco de Dados II Capítulo 1: SQL-PSM

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. Sintaxe: DELETE FROM tabela WHERE CURRENT OF cursor

Page 8: Banco de Dados II Capítulo 1: SQL-PSM

Um Exemplo em C:EXEC 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 9: Banco de Dados II Capítulo 1: SQL-PSM

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 CLIENTEWHERE CURRENT OF salCursor;

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

} EXEC SQL CLOSE salCursor;}

Page 10: Banco de Dados II Capítulo 1: SQL-PSM

Cursor

Scrolling cursors cursores movem-se por default do inicio do result

set para frente (forward) podemos, entretanto, movê-los também para trás

e/ou para qualquer posição no result set, para tanto, devemos acrescentar SCROLL na

definição do cursor EX. EXEC DECLARE meuCursor SCROLL

CURSOR FOR Empregado;

Page 11: Banco de Dados II Capítulo 1: SQL-PSM

Cursor

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 12: Banco de Dados II Capítulo 1: SQL-PSM

Integração Estreita com SGBDs

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

cliente - servidor Isto é muito bom para o desempenho

Page 13: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures

É um conjunto 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 14: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures

Vantagens:

1.Desempenho Ex.: Seja a consulta SELECT codigop, nome, COUNT(*) FROM

Projeto p, Alocacao a WHERE p.codproj = a.codigop

GROUP BY p.codproj, p.nome

Page 15: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures

Se vários usuários realizarem esta consulta o tráfego de rede será alto.

se criarmos uma stored procedure para executar esta consulta, os usuários necessitarão apenas de um comando para executar a consulta anterior: EXEC nomeProcedimento;

Outro ponto é a compilação, a consulta anterior seria compilada a cada chamada, enquanto o procedimento contendo a consulta seria compilado uma única vez

Page 16: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures - Vantagens 2. Facilita o gerenciamento do BD, pois a

consulta é escrita em um único lugar, portanto a manutenção desta torna-se mais eficaz e segura.

Page 17: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures - Vantagens 3. Segurança: podemos usar stored

procedures para limitar o acesso de alguns usuários ao BD. Desta forma, a maneira em que o BD pode ser modificado é estritamente definida.

Page 18: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures: SQL/PSM

SQL/PSM - Persistent Stored Modules: parte do padrão SQL relativo às Stored Procedures

No momento cada SGBD oferece sua própria linguagem (Oracle PL/SQL, Microsoft Transact/SQL, 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 19: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSM Criando Funções e Procedimentos

CREATE PROCEDURE <NOME> (<parâmetros>) declarações locaiscorpo do procedimento;

CREATE FUNCTION <NOME> RETURNS <tipo>

declarações locais corpo 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 20: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSMExemplo:

CREATE PROCEDURE MudaEndereco (IN endAntigo VARCHAR(255),IN endNovo VARCHAR(255)

)UPDATE EmpregadoSET endereco = endNovoWHERE endereco = endAntigo;

Page 21: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSMAlguns 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 encerraa função)

Page 22: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSM3) 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 END6) Labels: colocamos labels em comandos precedendo estespelo nome do label e dois pontos.7) Comandos condicionais 8) Laços

IF <condição> THEN LOOP<comandos> <Comandos>

ELSEIF <condição> THEN END LOOP;<comandos>

…ELSE <comandos>END IF;

Page 23: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSMExemplo: Função sobre o esquema Filmes que recebe um ano e nome de estúdio e retorna TRUE se aquele estúdio produziu apenas um filme preto e branco naquele ano ou nada produziu.CREATE FUNCTION PretoeBranco( a int, studio char[15])

RETURNS BOOLEANIF not exists (

select * from Filme where ano = a and nomeStudio = studio)

THEN RETURN TRUE; -- não faz a função retornar agoraELSEIF 1 <=

(select count(*) from Filme where ano = a andnomeStudio = nome and NOT emcores)

THEN RETURN TRUE;ELSE RETURN FALSE;END IF;

Page 24: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSMExemplo: Procedimento que calcula a média e variância de um

estúdioCREATE PROCEDURE MeanVar ( IN s char[15],

OUT mean REAL, OUT variance REAL)DECLARE NotFound FOR SQLSTATE ‘02000’;DECLARE filmeCursor CURSOR FOR

select duracao from Filme where nomeStudio = s;DECLARE novaDuracao INTEGER;DECLARE contaFilmes INTEGER;BEGIN

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

FETCH filmeCursor INTO novaDuracao;IF NotFound THEN LEAVE filmeCurdor END IF;SET contaFilmes = contaFilmes + 1;SET mean = mean + novaDuracao;SET variance = variance + novaDuracao * novaDuracao;

END LOOP;SET mean = mean / contaFilmes;SET variance = variance/contaFilmes - mean * mean;CLOSE filmeCursor;

END;

Page 25: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSM- For-Loops

usado para fazer iterator num cursorFOR <nome laço> AS <nome cursor> CURSOR FOR

<query>DO

<comandos>END FOR;

Veja exemplo no próximo slide!- WHILE <condição> DO

<comandos> END WHILE;

- REPEAT<comandos>

UNTIL <condição> END REPEAT;

Page 26: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSMExemplo: Mesmo procedimento de média e variância de estúdios,

usando FOR-LoopsCREATE PROCEDURE MeanVar ( IN s char[15],

OUT mean REAL, OUT variance REAL)DECLARE contaFilmes INTEGER;BEGIN

SET mean = 0.0;SET variance = 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 + novaDuracao;SET variance = variance + novaDuracao * novaDuracao;

END FOR;SET mean = mean / contaFilmes;SET variance = variance/contaFilmes - mean * mean;

END;

OBS.Veja que não é necessário OPEN, FETCH e CLOSE do cursor

Page 27: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSMExceções em PSM:É possível testar o SQLSTATE para verificar a ocorrência

de erros e tomar uma decisão, quando erros ocorramIsto é 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 28: Banco de Dados II Capítulo 1: SQL-PSM

Stored Procedures -SQL/PSMExemplo de exceções em PSM:

CREATE FUNCTION getSalario (mat integer) RETURNS FLOAT DECLARE NotFound CONDITION FOR SQLSTATE ‘02000’; DECLARE TooMany CONDITION FOR SQLSTATE ‘21000’;

BEGINDECLARE EXIT HANDLER FOR NotFound, TooMany

RETURN NULL;RETURN ( select salario

from Empregado where where matricula = mat);

END;

Page 29: Banco de Dados II Capítulo 1: SQL-PSM

PL-SQL : Oracle Stored Procedures Linguagem de desenvolvimento do Oracle que implementa

SQL/PSM Permite variáveis locais, laços, procedures, consulta a relações

“one tuple at a time”. Forma geral:

DECLAREdeclarações

BEGINcomandos executáveis;

EXCEPTIONComandos para manipular erros

(optativo)END;

A parte DECLARE é opcional.

Page 30: Banco de Dados II Capítulo 1: SQL-PSM

Oracle Stored Procedures

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

Existem dois tipos de blocos em PL/SQL:1. Anonymous Blocks: não possuem nomes (como

scripts) Podem ser escritas e executadas imediatamento no

iSQLPLUS Podem ser usadas num trigger

2. Named Blocks: Procedures Functions

Page 31: Banco de Dados II Capítulo 1: SQL-PSM

Blocos Anônimos

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

bloco */BEGIN (mandatory)

/* define-se os comandos que dizem o que o bloco faz*/EXCEPTION (optional)

/* define-se as ações que acontecem se uma exceção for lançado durante a execução deste bloco */

END; (mandatory)/

Page 32: Banco de Dados II Capítulo 1: SQL-PSM
Page 33: Banco de Dados II Capítulo 1: SQL-PSM

DECLARESintaxe

Exemplos

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;

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

Page 34: Banco de Dados II Capítulo 1: SQL-PSM

Declarando Variáveis com %TYPE

Exemplos

DECLARE sname Sailors.sname%TYPE; fav_boat VARCHAR2(30); my_fav_boat fav_boat%TYPE := 'Pinta';...

Acessando coluna sname na tabela Sailors

Acessando outra variável

Page 35: Banco de Dados II Capítulo 1: SQL-PSM

Criando um PL/SQL RecordUm 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_recordsailor_record_type;...BEGIN Sailor_record.sname:=‘peter’; Sailor_record.age:=45;…

Page 36: Banco de Dados II Capítulo 1: SQL-PSM

ProceduresObjetos armazenados no BD, que usam

comandos PL/SQL em seus corpos.

Declarações de ProcedureCREATE OR REPLACE PROCEDURE

<nome>(<lista_argumentos>) AS<declarações>

BEGIN <comandos PL/SQL>

END;

Page 37: Banco de Dados II Capítulo 1: SQL-PSM

PL-SQL : 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: padrão SQL + tipos genéricos como NUMBER = qualquer tipo inteiro ou real.

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

relação.atributo %TYPEpara capturar o tipo corretamente.

Page 38: Banco de Dados II Capítulo 1: SQL-PSM

Oracle: ExemploUma procedure que inclui uma nova cerveja e seu preço no menu do

bar RubroNegro.Vende(bar, cerveja, preço)

CREATE PROCEDURE MenuRubroNegro(c IN Vende.cerveja %TYPE,p IN Vende.preço %TYPE

) ASBEGIN

INSERT INTO VendeVALUES(`RubroNegro´´, c, p);

END;.run;

Note “run” somente armazena a procedure, não a executando.

Page 39: Banco de Dados II Capítulo 1: SQL-PSM

Oracle: Invocando ProceduresUma chamada a uma procedure pode

aparecer no corpo de um comando PL/SQL.

Exemplo:BEGIN

MenuRubroNegro('Bud', 2,50);MenuRubroNegro(‘Carlsberg', 5,00);

END;

Page 40: Banco de Dados II Capítulo 1: SQL-PSM

ORACLE PSMAtribuição de valores a variáveis é denotada por :=.

DesvioIF <condição> THEN

<comando(s)>ELSE

<comando(s)>END IF;

Em `ninhos´ de IFs, use ELSIF em lugar de ELSE IF.

LaçoLOOP

. . .EXIT WHEN <condição>

. . .END LOOP;

Page 41: Banco de Dados II Capítulo 1: SQL-PSM

Oracle: Consultas em PL/SQL Single-row selects permitem atribuir a

uma variável o resultado de uma consulta que produz uma única tupla.

Cursors permitem a recuperação de muitas tuplas, com o cursor e um laço sendo usados para processar tupla-a-tupla.

Page 42: Banco de Dados II Capítulo 1: SQL-PSM

Single-Row Select 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 retorna mais de uma tupla; neste caso, é preciso usar um cursor.

Exemplo Encontrar o preço da cerveja Schincariol no bar Tricolor.

Vende(bar, cerveja, preço)DECLARE

p Vende.preço %TYPE;BEGIN

SELECT preçoINTO pFROM VendeWHERE bar = `Tricolor´ AND cerveja =

`Schincariol´;END;

Page 43: Banco de Dados II Capítulo 1: SQL-PSM

CursoresDeclarados por:

CURSOR <nome> IScomando 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 é Verdade se não houver mais tupla a apontar. OPEN e CLOSE abrem e fecham um cursor,

respectivamente.

Page 44: Banco de Dados II Capítulo 1: SQL-PSM

Criando um Cursor Examplo:

DECLARE cursor c is select * from sailors;

sailorData sailors%ROWTYPE; BEGIN open c; fetch c into sailorData;

sailorData é uma variável que pode receber uma tupla da tabela sailors

Page 45: Banco de Dados II Capítulo 1: SQL-PSM

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; fetch rad_cursor into rad_val; area:=pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); close rad_cursor;END;/

radius3

6

8

Rad_cursor

fetch

Rad_val

Radius AreaAREAS

3 28.27

RAD_VALS

Page 46: Banco de Dados II Capítulo 1: SQL-PSM

Explicit Cursor AttributesObtém informação de status sobre um cursor.

Atributo Tipo Descrição

%ISOPEN Boolean Retorna TRUE is o cursor is open.

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

Page 47: Banco de Dados II Capítulo 1: SQL-PSM

ExemploUma procedure que examina o menu do bar

Tricolor e aumenta em 1,00 todos os preços que são menores que 3,00.

Vende(bar, cerveja, preço) Um simples UPDATE podia resolver o

problema, mas mudanças mais complicadas podiam exigir uma procedure.

Page 48: Banco de Dados II Capítulo 1: SQL-PSM

CREATE PROCEDURE Aumento() ASaCerveja Vende.cerveja%TYPE;oPreço Vende.preço%TYPE;CURSOR c IS

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

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 = `Tricolor´

AND cerveja = aCerveja;END IF;

END LOOP;CLOSE c;

END;

Page 49: Banco de Dados II Capítulo 1: SQL-PSM

Tipo ROWTYPEQualquer coisa (i.e., cursores, 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 50: Banco de Dados II Capítulo 1: SQL-PSM

Declarando Variáveis com %ROWTYPE

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

E como acessar oa campos de reserves_record?

reserves_record Reserves%ROWTYPE;

reserves_record.sid:=9; Reserves_record.bid:=877;

Acessando tabela Reserves

Page 51: Banco de Dados II Capítulo 1: SQL-PSM

ExemploA mesma procedure com a variável tupla cp.

CREATE PROCEDURE Aumento() ASCURSOR c IS

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

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

WHERE bar = `Tricolor´AND cerveja = cp.cerveja;

END IF;END LOOP;CLOSE c;

END;

Page 52: Banco de Dados II Capítulo 1: SQL-PSM

Definição de Function- Podemos definir uma função:

CREATE FUNCTION <func_name>(<param_list>) RETURN <return_type> AS ...No corpo da função, "RETURN <expression>;"

sai (retorna) da função e retorna o valor da

<expression>.

- Para descobrir quais procedures e functions você já criou:select object_type, object_namefrom user_objectswhere object_type = 'PROCEDURE' or object_type = 'FUNCTION';

Page 53: Banco de Dados II Capítulo 1: SQL-PSM

Removendo Procedures/Functions

Para remover uma stored procedure/function: drop procedure <procedure_name>;drop function <function_name>;

Page 54: Banco de Dados II Capítulo 1: SQL-PSM

Outras formas de Laços

Comando For permite que uma determinada sequencia de

comandos seja executada n vezes

FOR contador IN [REVERSE] valorInicial .. valorFinalLOOP

sequência de comandosEND LOOP

Page 55: Banco de Dados II Capítulo 1: SQL-PSM

Outras formas de Laços Comando For - Exemplo

Create procedure VerificaEstoqueDeclare

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

Beginselect Min(CodProduto), Max(codProduto)into codInicial, codFinalfrom Produtofor c in codInicial..codFinalloop

select estoque into estoquefrom produto where codProd = c and estoque>0Dbms_Output.Put_Line(‘O codigo ’|| c || ‘ tem em estoque’);

end loop;End

Page 56: Banco de Dados II Capítulo 1: SQL-PSM

Outras formas de Laços Comando while

Sintaxe:WHILE condição LOOP

ComandosEND LOOP;

Page 57: Banco de Dados II Capítulo 1: SQL-PSM

Loops: WHILE Loop

DECLARETEN 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 58: Banco de Dados II Capítulo 1: SQL-PSM

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 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 59: Banco de Dados II Capítulo 1: SQL-PSM

Manipulando Exceções Sintaxe:

EXCEPTIONWHEN nomeExceção 1 THEN

ComandosWHEN nomeExceção2 THEN

ComandosExemplo

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 60: Banco de Dados II Capítulo 1: SQL-PSM

Execeçõ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 61: Banco de Dados II Capítulo 1: SQL-PSM

Exemplo de ExceçãoDeclare Aux_X number(1); Subtype TipoX is Aux_X%Type; -- Limitado entre -9 e 9 x TipoX; y TipoX; Begin x := 10; Exception

when value_error then Dbms_Output.Put_Line(‘Valor fora do limite’);

End;

Page 62: Banco de Dados II Capítulo 1: SQL-PSM

Exceção definida pelo UsuárioDevem ser declaradas na área de declarações de um bloco ou procedure/function ou package

Comando:Declare

nomeExceção EXCEPTION;Begin

Sequencia de comandosIf … then

RAISE nomeExceção;End If;Comandos

ExceptionWhen NomeExceção then Comandos

End

Page 63: Banco de Dados II Capítulo 1: SQL-PSM

Exemplo: suponha a seguinte tabela:

Queremos armazenar quantas vezes alguém se loga ao BD

create table mylog(who varchar2(30), logon_num number

);

who logon_num

Peter 3

John 4

Moshe 2

mylog

Page 64: Banco de Dados II Capítulo 1: SQL-PSM

SoluçãoDECLARE cnt NUMBER;BEGIN select count(*) into cnt from mylog where who = user;

if cnt > 0 then update mylog set logon_num = logon_num + 1 where who = user; else insert into mylog values(user, 1); end if; commit;end;/

Page 65: Banco de Dados II Capítulo 1: SQL-PSM

Solução (2)

BEGIN update mylog set logon_num = logon_num + 1 where who = user;

if SQL%ROWCOUNT = 0 then insert into mylog values(user, 1); end if; commit;END;/

Page 66: Banco de Dados II Capítulo 1: SQL-PSM

create or replace procedure num_logged(person IN mylog.who%TYPE, num OUT mylog.logon_num%TYPE)ISBEGIN select logon_num into num from mylog where who = person;END;/

Exemplo- o que faz a SP abaixo?

who logon_num

Pete 3

John 4

Joe 2

Table mylog

Page 67: Banco de Dados II Capítulo 1: SQL-PSM

declare howmany mylog.logon_num%TYPE;begin num_logged(‘John',howmany); dbms_output.put_line(howmany);end;/

Chamando uma Procedure

Page 68: Banco de Dados II Capítulo 1: SQL-PSM

Erros numa Procedure/Function 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, digitre:

SHOW ERRORS FUNCTION myFunction

Page 69: Banco de Dados II Capítulo 1: SQL-PSM

create or replace function rating_message(rating IN NUMBER)return VARCHAR2ASBEGIN IF rating > 7 THEN return 'You are great'; ELSIF rating >= 5 THEN return 'Not bad'; ELSE return 'Pretty bad'; END IF;END;/

Exemplo de Function

NOTE que não especifica o tamanho

Page 70: Banco de Dados II Capítulo 1: SQL-PSM

declare paulRate:=9;Begin dbms_output.put_line(ratingMessage(paulRate));end;/

Chamando uma function

Page 71: Banco de Dados II Capítulo 1: SQL-PSM

Exemplos de SP em 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 72: Banco de Dados II Capítulo 1: SQL-PSM

Java Stored Procedure no Oracleimport 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 73: Banco de Dados II Capítulo 1: SQL-PSM

Java Stored Procedure no Oracle Carregando a Classe no Banco de dados:

> loadjava –u baptista BookDML.java

Acessando a classe:

create or replace procedure InsertBookJava(title varchar(), publisher varchar)AsLanguage javaName ‘BookDML.insertBook(java.lang.String, java.lang.String)’;

Executando do SQLPlus:

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

Page 74: Banco de Dados II Capítulo 1: SQL-PSM