Aula1

1,044
-1

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,044
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
27
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Aula1

  1. 1. Banco de Dados II Capítulo 1: SQL-PSM UFCG/DSC Bacharelado em Ciência da Computação Cláudio Baptista, Ph.D.
  2. 2. 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.
  3. 3. Cursor <ul><ul><li>No programa anterior uma única tupla é selecionada pelo SQL embutido. Geralmente, uma query resulta em várias tuplas. </li></ul></ul><ul><ul><li>Problema : SQL processa um conjunto de tuplas, enquanto que C e Pascal (ou outra linguagem host) processa um registro por vez. </li></ul></ul><ul><ul><li>Solução: Introduziu-se o conceito de cursor para permitir processar uma tupla por vez nas linguagens hospedeiras. </li></ul></ul>
  4. 4. Cursores <ul><li>Problema: “Impedance Mismatch” </li></ul><ul><ul><ul><li>SQL trabalha com relações </li></ul></ul></ul><ul><ul><ul><li>Linguagens de programação trabalham orientada a registro </li></ul></ul></ul><ul><ul><ul><li>Como fazer para ler os dados de um conjunto retornado pelo SQL numa linguagem de programação? </li></ul></ul></ul><ul><ul><ul><li>Precisamos ter um mecanismos para associar os valores retornados pelo SGBD em variáveis da aplicação. Faz-se isso usando variáveis hospedeiras. </li></ul></ul></ul>
  5. 5. Cursor <ul><ul><li>Um cursor pode ser visto como um ponteiro que aponta para uma única tupla(linha) do resultado da query. </li></ul></ul><ul><ul><li>Cada cursor possui uma busca associada, especificada como parte da operação que define o cursor. </li></ul></ul><ul><ul><li>A pesquisa é executada quando o cursor for aberto. </li></ul></ul><ul><ul><li>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. </li></ul></ul>
  6. 6. Cursor <ul><ul><li>Sintaxe da especificação de um cursor: EXEC SQL DECLARE nome-cursor CURSOR FOR cláusula-select </li></ul></ul><ul><ul><li>Um cursor possui as seguintes operações: </li></ul></ul><ul><ul><ul><li>OPEN: executa a query especificada e pões o cursos para apontar para uma posição anterior a primeira tupla do resultado da consulta </li></ul></ul></ul><ul><ul><ul><li>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. </li></ul></ul></ul><ul><ul><ul><li>CLOSE: fecha o cursor. </li></ul></ul></ul>
  7. 7. Cursor <ul><ul><ul><li>UPDATE … CURRENT OF: realiza a atualização dos atributos da tupla que está sendo apontada pelo cursor (linha corrente). Sintaxe: </li></ul></ul></ul><ul><ul><ul><ul><li>UPDATE tabela </li></ul></ul></ul></ul><ul><ul><ul><ul><li>SET lista de atribuições </li></ul></ul></ul></ul><ul><ul><ul><ul><li>WHERE CURRENT OF cursor </li></ul></ul></ul></ul><ul><ul><ul><li>DELETE ... CURRENT OF: elimina a tupla que está sendo apontada pelo cursor. Sintaxe: </li></ul></ul></ul><ul><ul><ul><ul><li>DELETE </li></ul></ul></ul></ul><ul><ul><ul><ul><li>FROM tabela </li></ul></ul></ul></ul><ul><ul><ul><ul><li>WHERE CURRENT OF cursor </li></ul></ul></ul></ul>
  8. 8. Um Exemplo em C: EXEC SQL BEGIN DECLARE SECTION; char SQLSTATE[6]; char titulo[101]; char ano[5]; EXEC SQL DECLARE filme_cursor CURSOR FOR SELECT titulo FROM filmes WHERE 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_cursor INTO :titulo; printf(“%sn”, titulo); }; EXEC SQL CLOSE filme_cursor; return; erro: printf(“Um Erro ocorreu!n”); };
  9. 9. 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 tuplas if (strcmp(SQLSTATE, “02000”)) break; if (salario > 10000) EXEC SQL DELETE FROM CLIENTE WHERE CURRENT OF salCursor; else EXEC SQL UPDATE CLIENTE SET salario = salario - salario * 0.2; WHERE CURRENT OF salCursor; } EXEC SQL CLOSE salCursor; }
  10. 10. Cursor <ul><li>Scrolling cursors </li></ul><ul><ul><li>cursores movem-se por default do inicio do result set para frente (forward) </li></ul></ul><ul><ul><li>podemos, entretanto, movê-los também para trás e/ou para qualquer posição no result set, </li></ul></ul><ul><ul><li>para tanto, devemos acrescentar SCROLL na definição do cursor </li></ul></ul><ul><ul><li>EX. EXEC DECLARE meuCursor SCROLL CURSOR FOR Empregado; </li></ul></ul>
  11. 11. Cursor <ul><li>Scrolling cursors </li></ul><ul><ul><li>Num FETCH, podemos adicionar as seguintes opções: </li></ul></ul><ul><ul><ul><li>NEXT ou PRIOR: pega o próximo ou anterior </li></ul></ul></ul><ul><ul><ul><li>FIRST ou LAST: obtém o primeiro ou último </li></ul></ul></ul><ul><ul><ul><li>RELATIVE seguido de um inteiro: indica quantas tuplas mover para frente (se positivo) ou para trás (se negativo) </li></ul></ul></ul><ul><ul><ul><li>ABSOLUTE seguido de um inteiro: indica a posição da tupla contando do início (se positivo) ou do final (se negativo) </li></ul></ul></ul>
  12. 12. Integração Estreita com SGBDs <ul><li>O uso de SQL/PSM (Stored Procedures) tais como PL/SQL, SQLJ, TransactSQL, … , são extensões da SQL </li></ul><ul><ul><li>Processadas no lado servidor da arquitetura cliente - servidor </li></ul></ul><ul><ul><ul><li>Isto é muito bom para o desempenho </li></ul></ul></ul>
  13. 13. Stored Procedures <ul><li>É um conjunto de comandos SQL definidos pelo usuário que ficam armazenados num BD como um procedimento/função, para eventuais processamentos. </li></ul><ul><li>São processamentos de tarefas da aplicação que residem no SGBD ao invés de no código da aplicação (cliente). </li></ul>
  14. 14. Stored Procedures <ul><li>Vantagens: </li></ul><ul><li>1. Desempenho </li></ul><ul><ul><li>Ex.: Seja a consulta </li></ul></ul><ul><ul><li>SELECT codigop, nome, COUNT(*) FROM Projeto p, Alocacao a WHERE p.codproj = a.codigop </li></ul></ul><ul><ul><li>GROUP BY p.codproj, p.nome </li></ul></ul>
  15. 15. Stored Procedures <ul><li>Se vários usuários realizarem esta consulta o tráfego de rede será alto. </li></ul><ul><li>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; </li></ul><ul><li>Outro ponto é a compilação, a consulta anterior seria compilada a cada chamada, enquanto o procedimento contendo a consulta seria compilado uma única vez </li></ul>
  16. 16. Stored Procedures - Vantagens <ul><li>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. </li></ul>
  17. 17. Stored Procedures - Vantagens <ul><li>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. </li></ul>
  18. 18. Stored Procedures: SQL/PSM <ul><li>SQL/PSM - Persistent Stored Modules: parte do padrão SQL relativo às Stored Procedures </li></ul><ul><li>No momento cada SGBD oferece sua própria linguagem (Oracle PL/SQL, Microsoft Transact/SQL, etc) </li></ul><ul><li>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. </li></ul>
  19. 19. Stored Procedures -SQL/PSM <ul><li>Criando Funções e Procedimentos </li></ul><ul><ul><li>CREATE PROCEDURE <NOME> (<parâmetros>) declarações locais corpo do procedimento; </li></ul></ul><ul><ul><li>CREATE FUNCTION <NOME> RETURNS <tipo> </li></ul></ul><ul><ul><li>declarações locais corpo da função; </li></ul></ul><ul><ul><ul><li>obs.: parâmetros são do tipo modo-nome-tipo (onde modo indica IN, OUT ou INOUT) </li></ul></ul></ul><ul><ul><ul><li>Parâmetros em funções devem ter modo IN </li></ul></ul></ul>
  20. 20. Stored Procedures -SQL/PSM Exemplo: CREATE PROCEDURE MudaEndereco ( IN endAntigo VARCHAR(255), IN endNovo VARCHAR(255) ) UPDATE Empregado SET endereco = endNovo WHERE endereco = endAntigo;
  21. 21. 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)
  22. 22. 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) Labels: colocamos labels em comandos precedendo estes pelo 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;
  23. 23. Stored Procedures -SQL/PSM Exemplo: 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 BOOLEAN IF not exists ( select * from Filme where ano = a and nomeStudio = studio) THEN RETURN TRUE; -- não faz a função retornar agora ELSEIF 1 <= (select count(*) from Filme where ano = a and nomeStudio = nome and NOT emcores) THEN RETURN TRUE; ELSE RETURN FALSE; END IF;
  24. 24. Stored Procedures -SQL/PSM Exemplo: Procedimento que calcula a média e variância de um estúdio CREATE 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;
  25. 25. Stored Procedures -SQL/PSM - For-Loops usado para fazer iterator num cursor FOR <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;
  26. 26. Stored Procedures -SQL/PSM Exemplo: Mesmo procedimento de média e variância de estúdios, usando FOR-Loops CREATE 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 é n ecessário OPEN, FETCH e CLOSE do cursor
  27. 27. Stored Procedures -SQL/PSM 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 tratadas 2) Código a ser executado quando exceção ocorrer 3) 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
  28. 28. Stored Procedures -SQL/PSM 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, TooMany RETURN NULL; RETURN ( select salario from Empregado where where matricula = mat); END;
  29. 29. PL-SQL : Oracle Stored Procedures <ul><li>Linguagem de desenvolvimento do Oracle que implementa SQL/PSM </li></ul><ul><li>Permite variáveis locais, laços, procedures, consulta a relações “one tuple at a time”. </li></ul><ul><li>Forma geral: </li></ul><ul><ul><li>DECLARE </li></ul></ul><ul><ul><li>declarações </li></ul></ul><ul><ul><li>BEGIN </li></ul></ul><ul><ul><li>comandos executáveis; </li></ul></ul><ul><ul><li>EXCEPTION </li></ul></ul><ul><ul><li>Comandos para manipular erros (optativo) </li></ul></ul><ul><ul><li>END; </li></ul></ul><ul><li>A parte DECLARE é opcional. </li></ul>
  30. 30. Oracle Stored Procedures <ul><li>Código PL/SQL é feito de blocos com uma única estrutura </li></ul><ul><li>Existem dois tipos de blocos em PL/SQL: </li></ul><ul><ul><li>Anonymous Blocks: não possuem nomes (como scripts) </li></ul></ul><ul><ul><ul><li>Podem ser escritas e executadas imediatamento no iSQLPLUS </li></ul></ul></ul><ul><ul><ul><li>Podem ser usadas num trigger </li></ul></ul></ul><ul><ul><li>2. Named Blocks: </li></ul></ul><ul><ul><ul><li>Procedures </li></ul></ul></ul><ul><ul><ul><li>Functions </li></ul></ul></ul>
  31. 31. Blocos Anônimos <ul><li>DECLARE (optional) </li></ul><ul><ul><li>/* aqui se declaram as variáveis que serão usadas no bloco */ </li></ul></ul><ul><li>BEGIN (mandatory) </li></ul><ul><ul><li>/* define-se os comandos que dizem o que o bloco faz*/ </li></ul></ul><ul><li>EXCEPTION (optional) </li></ul><ul><ul><li>/* define-se as ações que acontecem se uma exceção for lançado durante a execução deste bloco */ </li></ul></ul><ul><li>END; (mandatory) </li></ul><ul><li>/ </li></ul>
  32. 33. DECLARE Sintaxe 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…
  33. 34. 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
  34. 35. Criando um PL/SQL Record 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; …
  35. 36. Procedures <ul><li>Objetos armazenados no BD, que usam comandos PL/SQL em seus corpos. </li></ul><ul><li>Declarações de Procedure </li></ul><ul><ul><li>CREATE OR REPLACE PROCEDURE </li></ul></ul><ul><ul><li><nome>(<lista_argumentos>) AS </li></ul></ul><ul><ul><li><declarações> </li></ul></ul><ul><ul><li>BEGIN </li></ul></ul><ul><ul><li> <comandos PL/SQL> </li></ul></ul><ul><ul><li>END; </li></ul></ul>
  36. 37. PL-SQL : Oracle Stored Procedures <ul><li><Lista_argumentos> tem triplas nome-modo-tipo. </li></ul><ul><ul><li>Modo: IN, OUT, ou IN OUT para read-only, write-only, read/write, respectivamente. </li></ul></ul><ul><ul><li>Tipos: padrão SQL + tipos genéricos como NUMBER = qualquer tipo inteiro ou real. </li></ul></ul><ul><ul><li>Desde que tipos nas procedures devem casar com tipos no esquema do BD, pode-se usar uma expressão da forma </li></ul></ul><ul><ul><li>relação.atributo %TYPE </li></ul></ul><ul><ul><li>para capturar o tipo corretamente. </li></ul></ul>
  37. 38. Oracle: Exemplo <ul><li>Uma procedure que inclui uma nova cerveja e seu preço no menu do bar RubroNegro. </li></ul><ul><ul><li>Vende( bar , cerveja , preço) </li></ul></ul><ul><ul><li>CREATE PROCEDURE MenuRubroNegro( </li></ul></ul><ul><ul><li>c IN Vende.cerveja %TYPE, </li></ul></ul><ul><ul><li>p IN Vende.preço %TYPE </li></ul></ul><ul><ul><li>) AS </li></ul></ul><ul><ul><li>BEGIN </li></ul></ul><ul><ul><li>INSERT INTO Vende </li></ul></ul><ul><ul><li>VALUES(`RubroNegro´´, c, p); </li></ul></ul><ul><ul><li>END; </li></ul></ul><ul><ul><li>. </li></ul></ul><ul><ul><li>run; </li></ul></ul><ul><li>Note “ run ” somente armazena a procedure, não a executando. </li></ul>
  38. 39. Oracle: Invocando Procedures <ul><li>Uma chamada a uma procedure pode aparecer no corpo de um comando PL/SQL. </li></ul><ul><li>Exemplo: </li></ul><ul><ul><li>BEGIN </li></ul></ul><ul><ul><li>MenuRubroNegro('Bud', 2,50); </li></ul></ul><ul><ul><li>MenuRubroNegro(‘Carlsberg', 5,00); </li></ul></ul><ul><ul><li>END; </li></ul></ul>
  39. 40. ORACLE PSM <ul><li>Atribuição de valores a variáveis é denotada por := . </li></ul><ul><li>Desvio </li></ul><ul><ul><li>IF <condição> THEN </li></ul></ul><ul><ul><li> <comando(s)> </li></ul></ul><ul><ul><li>ELSE </li></ul></ul><ul><ul><li> <comando(s)> </li></ul></ul><ul><ul><li>END IF; </li></ul></ul><ul><li>Em `ninhos´ de IFs, use ELSIF em lugar de ELSE IF . </li></ul><ul><li>Laço </li></ul><ul><ul><li>LOOP </li></ul></ul><ul><ul><li>. . . </li></ul></ul><ul><ul><li>EXIT WHEN <condição> </li></ul></ul><ul><ul><li>. . . </li></ul></ul><ul><ul><li>END LOOP; </li></ul></ul>
  40. 41. Oracle: Consultas em PL/SQL <ul><li>Single-row selects permitem atribuir a uma variável o resultado de uma consulta que produz uma única tupla. </li></ul><ul><li>Cursors permitem a recuperação de muitas tuplas, com o cursor e um laço sendo usados para processar tupla-a-tupla. </li></ul>
  41. 42. Single-Row Select <ul><li>Um select-from-where em PL/SQL deve ter uma cláusula INTO listando as variáveis que recebem os resultados da consulta . </li></ul><ul><li>Ocorre erro se o select-from-where retorna mais de uma tupla; neste caso, é preciso usar um cursor. </li></ul><ul><li>Exemplo </li></ul><ul><li>Encontrar o preço da cerveja Schincariol no bar Tricolor. </li></ul><ul><ul><li>Vende( bar , cerveja , preço) </li></ul></ul><ul><ul><li>DECLARE </li></ul></ul><ul><ul><li>p Vende.preço %TYPE; </li></ul></ul><ul><ul><li>BEGIN </li></ul></ul><ul><ul><li>SELECT preço </li></ul></ul><ul><ul><li>INTO p </li></ul></ul><ul><ul><li>FROM Vende </li></ul></ul><ul><ul><li>WHERE bar = `Tricolor´ AND cerveja = `Schincariol´; </li></ul></ul><ul><ul><li>END; </li></ul></ul>
  42. 43. Cursores <ul><li>Declarados por: </li></ul><ul><ul><li>CURSOR <nome> IS </li></ul></ul><ul><ul><li>comando select-from-where </li></ul></ul><ul><li>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. </li></ul><ul><ul><li>Fetch statement: </li></ul></ul><ul><ul><li>FETCH <nome_cursor> INTO </li></ul></ul><ul><ul><li>lista_variáveis; </li></ul></ul><ul><li>Um laço é interrompido por: </li></ul><ul><ul><li>EXIT WHEN <nome_cursor> %NOTFOUND; </li></ul></ul><ul><ul><li>O valor é Verdade se não houver mais tupla a apontar. </li></ul></ul><ul><li>OPEN e CLOSE abrem e fecham um cursor, respectivamente . </li></ul>
  43. 44. Criando um Cursor <ul><li>Examplo: </li></ul><ul><li>DECLARE </li></ul><ul><li> cursor c is select * from sailors; </li></ul><ul><li>sailorData sailors%ROWTYPE; </li></ul><ul><li>BEGIN </li></ul><ul><li>open c; </li></ul><ul><li>fetch c into sailorData; </li></ul>sailorData é uma variável que pode receber uma tupla da tabela sailors
  44. 45. 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; / Rad_cursor fetch Rad_val Radius Area AREAS 3 28.27 RAD_VALS radius 3 6 8
  45. 46. Explicit Cursor Attributes Obté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.
  46. 47. Exemplo <ul><li>Uma procedure que examina o menu do bar Tricolor e aumenta em 1,00 todos os preços que são menores que 3,00. </li></ul><ul><ul><li>Vende( bar , cerveja , preço) </li></ul></ul><ul><li>Um simples UPDATE podia resolver o problema, mas mudanças mais complicadas podiam exigir uma procedure. </li></ul>
  47. 48. <ul><ul><li>CREATE PROCEDURE Aumento() AS </li></ul></ul><ul><ul><li>aCerveja Vende.cerveja%TYPE; </li></ul></ul><ul><ul><li>oPreço Vende.preço%TYPE; </li></ul></ul><ul><ul><li>CURSOR c IS </li></ul></ul><ul><ul><li>SELECT cerveja, preço </li></ul></ul><ul><ul><li>FROM Vende </li></ul></ul><ul><ul><li>WHERE bar =`Tricolor´; </li></ul></ul><ul><ul><li>BEGIN </li></ul></ul><ul><ul><li>OPEN c; </li></ul></ul><ul><ul><li>LOOP </li></ul></ul><ul><ul><li>FETCH c INTO aCerveja, oPreço; </li></ul></ul><ul><ul><li>EXIT WHEN c%NOTFOUND; </li></ul></ul><ul><ul><li>IF oPreço < 3.00 THEN </li></ul></ul><ul><ul><li>UDPATE Vende </li></ul></ul><ul><ul><li>SET preço = oPreço + 1.00 </li></ul></ul><ul><ul><li>WHERE bar = `Tricolor´ </li></ul></ul><ul><ul><li>AND cerveja = aCerveja; </li></ul></ul><ul><ul><li>END IF; </li></ul></ul><ul><ul><li>END LOOP; </li></ul></ul><ul><ul><li>CLOSE c; </li></ul></ul><ul><ul><li>END; </li></ul></ul>
  48. 49. Tipo ROWTYPE <ul><li>Qualquer coisa ( i.e ., cursores, nomes de tabela) que tem um tipo tupla pode ter seu tipo capturado com %ROWTYPE . </li></ul><ul><li>Pode-se criar variáveis temporárias tipo tupla e acessar seus componentes como variável.componente (“dot notation”). </li></ul><ul><li>Muito útil, principalmente se a tupla tem muitos componentes. </li></ul>
  49. 50. 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
  50. 51. Exemplo <ul><li>A mesma procedure com a variável tupla cp . </li></ul><ul><ul><li>CREATE PROCEDURE Aumento() AS </li></ul></ul><ul><ul><li>CURSOR c IS </li></ul></ul><ul><ul><li>SELECT cerveja, preço </li></ul></ul><ul><ul><li>FROM Vende </li></ul></ul><ul><ul><li>WHERE bar = `Tricolor´; </li></ul></ul><ul><ul><li>cp c %ROWTYPE; </li></ul></ul><ul><ul><li>BEGIN </li></ul></ul><ul><ul><li>OPEN c; </li></ul></ul><ul><ul><li>LOOP </li></ul></ul><ul><ul><li>FETCH c INTO cp; </li></ul></ul><ul><ul><li>EXIT WHEN c %NOTFOUND; </li></ul></ul><ul><ul><li>IF cp.preço < 3.00 THEN </li></ul></ul><ul><ul><li>UDPATE Vende </li></ul></ul><ul><ul><li>SET preço= cp.preço + 1.00 </li></ul></ul><ul><ul><li>WHERE bar = `Tricolor´ </li></ul></ul><ul><ul><li>AND cerveja = cp.cerveja; </li></ul></ul><ul><ul><li>END IF; </li></ul></ul><ul><ul><li>END LOOP; </li></ul></ul><ul><ul><li>CLOSE c; </li></ul></ul><ul><ul><li>END; </li></ul></ul>
  51. 52. Definição de Function - Podemos definir uma função: CREATE FUNCTION <func_name>(<param_list>) RETURN <return_type> AS ... No corpo da função, &quot;RETURN <expression>;&quot; sai (retorna) da função e retorna o valor da <expression>. - Para descobrir quais procedures e functions você já criou: select object_type, object_name from user_objects where object_type = 'PROCEDURE' or object_type = 'FUNCTION';
  52. 53. Removendo Procedures/Functions Para remover uma stored procedure/function: drop procedure <procedure_name>; drop function <function_name>;
  53. 54. Outras formas de Laços <ul><li>Comando For </li></ul><ul><ul><li>permite que uma determinada sequencia de comandos seja executada n vezes </li></ul></ul>FOR contador IN [REVERSE] valorInicial .. valorFinal LOOP sequência de comandos END LOOP
  54. 55. Outras formas de Laços <ul><li>Comando For - Exemplo </li></ul>Create procedure VerificaEstoque Declare codInicial Produto.codProduto%Type; codFinal CodInicial%Type; estoque Produto.estoque%Type; Begin select Min(CodProduto), Max(codProduto) into codInicial, codFinal from Produto for c in codInicial..codFinal loop select estoque into estoque from produto where codProd = c and estoque>0 Dbms_Output.Put_Line(‘O codigo ’|| c || ‘ tem em estoque’); end loop; End
  55. 56. Outras formas de Laços <ul><li>Comando while </li></ul>Sintaxe: WHILE condição LOOP Comandos END LOOP;
  56. 57. Loops: WHILE Loop DECLARE 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;
  57. 58. Manipulando Exceções <ul><li>Exceções são todos os erros e imprevistos que podem ocorrer durante a execução de um bloco PL/SQL </li></ul><ul><li>Quando uma exceção ocorre o Oracle aborta a execução e procura a área de exceções (EXCEPTION) para tratar a falha. </li></ul><ul><li>As exceções podem ser </li></ul><ul><ul><li>Pré-definidas </li></ul></ul><ul><ul><li>Definidas pelo usuário </li></ul></ul>
  58. 59. Manipulando Exceções Sintaxe: EXCEPTION WHEN nomeExceção 1 THEN Comandos WHEN nomeExceção2 THEN Comandos Exemplo begin insert into Pais values (100, ‘Brasil’); Commit; Dbms_Output.Put_Line(‘Inserção realizada com sucesso’); Exception when 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;
  59. 60. Execeções Pré-definidas <ul><li>Cursor_Already_Open </li></ul><ul><li>DUP_Val_On_INDEX </li></ul><ul><li>INVALID_CURSOR </li></ul><ul><li>Invalid_Number </li></ul><ul><li>Login_Denied </li></ul><ul><li>No_Data_Found </li></ul><ul><li>Not_Logged_On </li></ul><ul><li>RowType_Mismatch </li></ul><ul><li>Storage_Error </li></ul><ul><li>Too_Many_Rows </li></ul><ul><li>Value_Error </li></ul><ul><li>Zero_Divide </li></ul><ul><li>Others </li></ul>
  60. 61. Exemplo de Exceção Declare 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;
  61. 62. 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 Sequencia de comandos If … then RAISE nomeExceção; End If; Comandos Exception When NomeExceção then Comandos End
  62. 63. Exemplo: suponha a seguinte tabela: <ul><li>Queremos armazenar quantas vezes alguém se loga ao BD </li></ul>create table mylog( who varchar2(30), logon_num number ); mylog logon_num who 3 Peter 4 John 2 Moshe
  63. 64. Solução DECLARE 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; /
  64. 65. 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; /
  65. 66. create or replace procedure num_logged (person IN mylog.who%TYPE, num OUT mylog.logon_num%TYPE) IS BEGIN select logon_num into num from mylog where who = person; END; / Exemplo- o que faz a SP abaixo? Table mylog logon_ num who 3 Pete 4 John 2 Joe
  66. 67. declare howmany mylog.logon_num%TYPE; begin num_logged( ‘ John',howmany); dbms_output.put_line(howmany); end; / Chamando uma Procedure
  67. 68. Erros numa Procedure/Function <ul><li>Quando se cria uma procedure, se houver erros na sua definição, estes não serão mostrados </li></ul><ul><li>Para ver os erros de procedure chamada myProcedure , digite: </li></ul><ul><ul><li>SHOW ERRORS PROCEDURE myProcedure </li></ul></ul><ul><li>no iSQLPLUS prompt </li></ul><ul><li>Para funções, digitre: </li></ul><ul><ul><li>SHOW ERRORS FUNCTION myFunction </li></ul></ul>
  68. 69. create or replace function rating_message(rating IN NUMBER) return VARCHAR2 AS BEGIN 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
  69. 70. declare paulRate:=9; Begin dbms_output.put_line(ratingMessage(paulRate)); end; / Chamando uma function
  70. 71. Exemplos de SP em SQL Server
  71. 72. Java Stored Procedure no 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()); } }
  72. 73. 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) As Language java Name ‘BookDML.insertBook(java.lang.String, java.lang.String)’; Executando do SQLPlus: CALL insertBookJava(´Meulivro´, ´LMV´);

×