A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

PL/SQL (Procedural Language/Structured Query Language)

Apresentações semelhantes


Apresentação em tema: "PL/SQL (Procedural Language/Structured Query Language)"— Transcrição da apresentação:

1 PL/SQL (Procedural Language/Structured Query Language)
SCC Bancos de Dados e Suas Aplicações Prof. José Fernando Rodrigues Júnior PL/SQL (Procedural Language/Structured Query Language) Material original: Profa. Elaine Parros Machado de Sousa

2 Contexto de programação
1GL – linguagem de máquina, 0´s e 1´s 2 GL – assembly, mnemônicos como LOAD e STORE 3 GL – de alto nível, como C, Java, ... 4 GL – declarações que abstraem os algoritmos e estruturas, como SQL 5 GL – programação visual

3 PL/SQL PL/SQL combina flexibilidade da SQL (4 GL) com construções procedimen-tais do PL/SQL (3GL) estende SQL: variáveis e tipos estruturas de controle procedimentos e funções tipos de objeto e métodos

4 PL/SQL PL/SQL engine  tecnologia compila e executa blocos PL/SQL
pode ser instalado em: servidor Oracle stored procedures e triggers blocos anônimos. Ex: Ferramentas de desenvolvimento PL/SQL: SQLPlus, SQL Developer, Rapid SQL, DBPartner, SQL Navigator, TOAD, SQL-Programmer, PL/SQL Developer, ... Pré-compiladores (ex: Pro*C/C++), ODBC, JDBC, OCI ... ferramentas Oracle Oracle Forms Oracle Reports

5 PL/SQL PL/SQL engine  tecnologia Outras combinações 3GL/4GL:
compila e executa blocos PL/SQL pode ser instalado em: servidor Oracle stored procedures e triggers blocos anônimos. Ex: Ferramentas de desenvolvimento PL/SQL: SQLPlus, SQL Developer, Rapid SQL, DBPartner, SQL Navigator, TOAD, SQL-Programmer, PL/SQL Developer, ... Pré-compiladores (ex: Pro*C/C++), ODBC, JDBC, OCI ... ferramentas Oracle Oracle Forms Oracle Reports Outras combinações 3GL/4GL: PostgreSQL – PL/pgSQL IBM DB2 – SQL PL Microsoft SQL Server - Transact-SQL

6 PL/SQL Engine PostgreSQL – PL/pgSQL DB2 – SQL PL Microsoft SQL Server - Transact-SQL Figura retirada de PL/SQL User’s Guide and Reference (Release 2 (9.2))

7 PL/SQL – Tráfego em Rede
Servidor de BD Servidor de BD Bloco PL/SQL SQL SQL SQL SQL … SQL … SQL Pode-se, por exemplo, criar um procedimento PL/SQL que cria sentenças SQL dinamicamente. Todas as sentenças criadas serão enviadas por meio de uma única requisição ao servidor, com menor quantidade de dados trafegando pela rede. No entanto, o processamento das instruções terá o mesmo custo se comparado ao envio de cada instrução por vez. Aplicação Cliente Aplicação Cliente

8 PL/SQL Vantagens suporte a SQL suporta a programação OO performance
produtividade integração com Oracle resolve “encruzilhadas” SQL

9 PL/SQL Recursos estrutura em blocos variáveis e tipos
tratamento de erros estruturas de controle condicionais repetição cursores procedimentos e funções pacotes coleções conceitos OO

10 Princípios básicos PL/SQL
Estrutura em 3 blocos DECLARE /*variáveis, tipos, cursores, subprogramas, ... */ BEGIN /* instruções... */ EXCEPTION /*tratamento de exceções*/ END;

11 Princípios básicos PL/SQL
Declaração/Inicialização de Variáveis nome [CONSTANT] tipo [NOT NULL] [DEFAULT] [:= valor]

12 Princípios básicos PL/SQL
Exemplo SET SERVEROUTPUT ON; DECLARE v_count NUMBER; BEGIN SELECT count(*) INTO v_count FROM aluno; dbms_output.put_line('NAlunos = ' || v_count); END;

13 Exemplo DECLARE v_nome LBD01_VINCULO_USP.nome%TYPE; v_idade LBD01_VINCULO_USP.NROUSP%TYPE; Equivale a: v_nome VARCHAR2(100); v_nusp NUMBER(7,0);  O %TYPE faz com que o SGBD descubra qual é o tipo daquele dado no bd. OBS: nas exceções, é possível dar o mesmo tratamento para mais de um tipo de exceção, usando OR: when exc1 OR exc2 then ....

14 Exemplo – SELECT INTO set serveroutput on; DECLARE
v_nome L01_Morador.mnome%TYPE; v_cpf L01_Morador.mcpf%TYPE; BEGIN SELECT mnome, mcpf INTO v_nome, v_cpf FROM L01_Morador A WHERE A.mcpf = 1; dbms_output.put_line('Nome '|| v_nome || ', CPF ' || v_cpf); EXCEPTION /* exceções associadas ao SELECT INTO */ WHEN NO_DATA_FOUND THEN dbms_output.put_line('Morador não encontrado'); /*se nusp não fosse único...*/ WHEN TOO_MANY_ROWS THEN dbms_output.put_line('Há mais de um morador com este CPF'); END; OBS: nas exceções, é possível dar o mesmo tratamento para mais de um tipo de exceção, usando OR: when exc1 OR exc2 then ....

15 Exemplo DECLARE v_vinculo LBD01_VINCULO_USP%ROWTYPE; Equivale a: v_vinculo VARCHAR2(100),v_nusp NUMBER(7,0),...  O %ROWTYPE faz com que o SGBD descubra qual é o tipo de tuplas inteiras OBS: nas exceções, é possível dar o mesmo tratamento para mais de um tipo de exceção, usando OR: when exc1 OR exc2 then ....

16 Exemplo – SELECT INTO DECLARE v_morador L01_Morador%ROWTYPE; BEGIN
SELECT * INTO v_morador FROM L01_Morador A WHERE A.mcpf = 1; dbms_output.put_line('Nome '|| v_morador.mnome || ', CPF ' || v_morador.mcpf); EXCEPTION /* exceções associadas ao SELECT INTO */ WHEN NO_DATA_FOUND THEN dbms_output.put_line('Morador não encontrado'); /*se nusp não fosse único...*/ WHEN TOO_MANY_ROWS THEN dbms_output.put_line('Há mais de um morador com este CPF'); END; OBS: nas exceções, é possível dar o mesmo tratamento para mais de um tipo de exceção, usando OR: when exc1 OR exc2 then ....

17 Princípios básicos PL/SQL
Estruturas de controle de fluxo IF ... THEN .... END IF; IF ... THEN .... ELSE ... END IF; IF ... THEN .... ELSIF ... THEN... ELSE ... END IF; CASE <variável> WHEN <valor> THEN <instruções> WHEN ... THEN... .... ELSE ... /*opcional*/ END CASE;

18 Exemplo - INSERT DECLARE v_count_turma NUMBER; v_count_aluno NUMBER; BEGIN SELECT COUNT(*) INTO v_count_turma FROM lbd07_TURMA L WHERE L.CODDISC = 'SSC0722' and L.ano = EXTRACT (YEAR FROM SYSDATE) and L.NROTURMA = 1; IF v_count_turma = 0 THEN INSERT INTO LBD07_TURMA VALUES(1,EXTRACT (YEAR FROM SYSDATE),'SSC0722',31); dbms_output.put_line('Nova turma criada'); END IF; SELECT COUNT(*) INTO v_count_aluno FROM lbd08_matricula M WHERE M.CODDISC = 'SSC0722' and M.ano = EXTRACT (YEAR FROM SYSDATE) and M.NROTURMA = 1; IF v_count_aluno < 5 THEN INSERT INTO lbd08_matricula(NROUSP,CODDISC,ANO,NROTURMA,NOTA) VALUES (1,'SSC0722',EXTRACT (YEAR FROM SYSDATE),1, 0); dbms_output.put_line('Aluno matriculado'); ELSE dbms_output.put_line('Turma lotada'); END; Total de turmas SSC0722 do ano atual, da turma 1 (deve ser igual a 1) Se o total == 0, a turma não existe e deve ser criada. Total de alunos da turma (no máximo 5). DELETE FROM lbd08_matricula M WHERE M.CODDISC = 'SSC0722' and M.ano = EXTRACT (YEAR FROM SYSDATE) and M.NROTURMA = 1; DELETE FROM lbd07_TURMA M Se o total de alunos < 5, cabem mais alunos – matricula o novo aluno.

19 Exemplo - INSERT DECLARE v_count_turma NUMBER; v_count_aluno NUMBER;
BEGIN SELECT COUNT(*) INTO v_count_turma FROM lbd07_TURMA L WHERE L.CODDISC = 'SSC0722' and L.ano = EXTRACT (YEAR FROM SYSDATE) and L.NROTURMA = 1; IF v_count_turma = 0 THEN INSERT INTO LBD07_TURMA VALUES(1,EXTRACT (YEAR FROM SYSDATE),'SSC0722',31); dbms_output.put_line('Nova turma criada'); END IF; SELECT COUNT(*) INTO v_count_aluno FROM lbd08_matricula M WHERE M.CODDISC = 'SSC0722' and M.ano = EXTRACT (YEAR FROM SYSDATE) and M.NROTURMA = 1; IF v_count_aluno < 5 THEN INSERT INTO lbd08_matricula(NROUSP,CODDISC,ANO,NROTURMA,NOTA) VALUES (1,'SSC0722',EXTRACT (YEAR FROM SYSDATE),1, 0); dbms_output.put_line('Aluno matriculado'); ELSE dbms_output.put_line('Turma lotada'); END; DELETE FROM lbd08_matricula M WHERE M.CODDISC = 'SSC0722' and M.ano = EXTRACT (YEAR FROM SYSDATE) and M.NROTURMA = 1; DELETE FROM lbd07_TURMA M

20 Exemplo - Exceção Total de alunos da turma (no máximo 5).
DECLARE v_count_aluno NUMBER; exc_lotada EXCEPTION; BEGIN SELECT COUNT(*) INTO v_count_aluno FROM lbd08_matricula M WHERE M.CODDISC = 'SSC0722' and M.ano = EXTRACT (YEAR FROM SYSDATE) and M.NROTURMA = 1; IF v_count_aluno < 5 THEN INSERT INTO lbd08_matricula(NROUSP,CODDISC,ANO,NROTURMA,NOTA) VALUES (6,'SSC0722',EXTRACT (YEAR FROM SYSDATE),1, 0); ELSE RAISE exc_lotada; END IF; EXCEPTION WHEN exc_lotada THEN dbms_output.put_line('Turma lotada'); WHEN OTHERS THEN dbms_output.put_line('Erro nro: ' || SQLCODE || '. Mensagem: ' || SQLERRM ); END; Total de alunos da turma (no máximo 5). Se o total de alunos < 5, cabem mais alunos – matricula o novo aluno. Trocar o 5 por 10  exc_lotada Trocar o 6 por 1000  raise others SQLCODE e SQLERR – funções - possível usar o SQLCODE num if SQLCODE… ???? Em execeção definida pelo usuário: SQLCODE retorna 1 e SQLERR retorna “Exceção definida pelo usuário”

21 Exemplo - Exceção DECLARE v_count_aluno NUMBER; exc_lotada EXCEPTION;
BEGIN SELECT COUNT(*) INTO v_count_aluno FROM lbd08_matricula M WHERE M.CODDISC = 'SSC0722' and M.ano = EXTRACT (YEAR FROM SYSDATE) and M.NROTURMA = 1; IF v_count_aluno < 5 THEN INSERT INTO lbd08_matricula(NROUSP,CODDISC,ANO,NROTURMA,NOTA) VALUES (6,'SSC0722',EXTRACT (YEAR FROM SYSDATE),1, 0); ELSE RAISE exc_lotada; END IF; EXCEPTION WHEN exc_lotada THEN dbms_output.put_line('Turma lotada'); WHEN OTHERS THEN dbms_output.put_line('Erro nro: ' || SQLCODE || '. Mensagem: ' || SQLERRM ); END; Trocar o 5 por 10  exc_lotada Trocar o 6 por 1000  raise others SQLCODE e SQLERR – funções - possível usar o SQLCODE num if SQLCODE… ???? Em execeção definida pelo usuário: SQLCODE retorna 1 e SQLERR retorna “Exceção definida pelo usuário”

22 Princípios básicos PL/SQL
Estruturas de Repetição LOOP <instruções> EXIT WHEN <condição de parada> END LOOP; WHILE <condição de parada> LOOP <instruções> END LOOP; FOR <contador> IN [REVERSE] <min>..<max> no REVERSE o min ainda é colocado primeiro

23 Exemplo DECLARE v_disciplina LBD07_TURMA.CODDISC%TYPE;
v_anoTurma LBD07_TURMA.ANO%TYPE; BEGIN v_disciplina := 'SSC0722'; v_anoTurma := EXTRACT (YEAR FROM SYSDATE); /* insere 6 turmas na disciplina SCC103 */ FOR nroTurma IN 1..8 LOOP INSERT INTO LBD07_TURMA VALUES (nroTurma, v_anoTurma, v_disciplina, 31); dbms_output.put_line('Turma ' || nroTurma || ' criada.'); END LOOP; EXCEPTION WHEN OTHERS THEN dbms_output.put_line('Erro nro: ' || SQLCODE || '. Mensagem: ' || SQLERRM ); END; DELETE FROM lbd08_matricula M WHERE M.CODDISC = 'SSC0722' and M.ano = EXTRACT (YEAR FROM SYSDATE) and M.NROTURMA = 1; DELETE FROM lbd07_TURMA M

24 Cursores Área de contexto Cursor
área de memória com informações de processamento de uma instrução inclui conjunto ativo  linhas retornadas por uma consulta Cursor handle para uma área de contexto (cursor NÃO é uma variável de memória) tipos: implícito explícito

25 Cursor Explícito DECLARE CURSOR c1 IS SELECT empno, ename, job
FROM emp WHERE deptno = 20; Figura retirada de PL/SQL User’s Guide and Reference (Release 2 (9.2))

26 Cursor Explícito Passos: declarar o cursor abrir o cursor
OPEN buscar resultados FETCH – retorna uma tupla por vez e avança para a próxima no conjunto ativo fechar cursor CLOSE

27 Cursor Explícito Atributos do tipo CURSOR FOUND
NULL se ainda não houve nenhum FETCH true se o FETCH anterior retornou uma tupla false caso contrário NOTFOUND: !FOUND ISOPEN ROWCOUNT nro de tuplas já lidas por FETCH

28 Exemplo – Cursor Explícito
DECLARE CURSOR c_alunos IS SELECT * FROM lbd03_aluno; v_alunos c_alunos%ROWTYPE; BEGIN OPEN c_alunos; /*abre cursor - executa consulta */ LOOP FETCH c_alunos INTO v_alunos; /*recupera tupla*/ /*sai do loop se não há mais tuplas*/ EXIT WHEN c_alunos%NOTFOUND; dbms_output.put_line('NUSP: ' || v_alunos.nrousp || ' - Idade: ' || v_alunos.idade); END LOOP; CLOSE c_alunos; /*fecha cursor*/ END; exceção NO_DATA_FOUND só é levantada para select into.... em cursor, o atributo NOTFOUND fica TRUE OBS: %ROWTYPE pode ser usado para o cursor tb! Ex: v_alunos c_alunos%ROWTYPE

29 Exemplo – CURSOR ... FOR UPDATE
DECLARE CURSOR c_alunos IS SELECT M.nrousp, A.nome, M.nota FROM lbd08_matricula M JOIN lbd01_vinculo_usp A ON M.nrousp = A.nrousp WHERE M.coddisc='SSC0722' AND M.ano=2009 FOR UPDATE OF M.nota; /*FOR UPDATE OF – registros ficam bloqueados para a seção corrente*/ v_resultado c_alunos%ROWTYPE; /*ROWTYPE associado a cursor*/ BEGIN OPEN c_alunos; LOOP FETCH c_alunos INTO v_resultado; EXIT WHEN c_alunos%NOTFOUND; dbms_output.put_line('Aluno: ' || v_resultado.nrousp || ' - ' || v_resultado.nome || ' Nota: ' || v_resultado.nota); IF v_resultado.nota = 4.99 THEN UPDATE lbd08_matricula SET nota = 5.0 WHERE CURRENT OF c_alunos; /*para update ou delete*/ /*CURRENT OF se refere necessariamente a um único registro*/ /*o uso é vinculado a cursores FOR UPDATE OF para update e delete*/ END IF; END LOOP; COMMIT; /*Release FOR UPDATE records*/ CLOSE c_alunos; END; Exemplo – CURSOR ... FOR UPDATE Atualizar na tabela a linha correspondente à linha atual do cursor => deve ser declarado como FOR UPDATE e a atualização será feita com base no indicador de linha atual (CURRENT OF) FOR UPDATE OF: Linhas de uma tabela são bloqueadas somente se a clausula FOR UPDATE OF referir-se a uma coluna daquela tabela. FOR UPDATE OF não requer nomes de colunas como parâmetros, no entanto, quando o cursor vier de uma junção, o uso dos nomes de coluna servem para identificar qual das tabelas envolvidas na junção terão seus registros bloqueados. “When querying multiple tables, you can use the FOR UPDATE clause to confine row locking to particular tables. Rows in a table are locked only if the FOR UPDATE OF clause refers to a column in that table. For example, the following query locks rows in the emp table but not in the dept table: DECLARE CURSOR c1 IS SELECT ename, dname FROM emp, dept WHERE emp.deptno = dept.deptno AND job = 'MANAGER' FOR UPDATE OF sal;” OBS: COLOCAR UM EXEMPLO COM JUNÇÃO NO UPDATE OF, PARA NÃO PARECER QUE PODE SER UMA TABELA SÓ!

30 CURSOR c_alunos IS SELECT M.nrousp, A.nome, M.nota
DECLARE CURSOR c_alunos IS SELECT M.nrousp, A.nome, M.nota FROM lbd08_matricula M JOIN lbd01_vinculo_usp A ON M.nrousp = A.nrousp WHERE M.coddisc='SSC0722' AND M.ano=2009 FOR UPDATE OF M.nota; /*FOR UPDATE OF – registros ficam bloqueados para a seção corrente*/ v_resultado c_alunos%ROWTYPE; /*ROWTYPE associado a cursor*/ BEGIN OPEN c_alunos; LOOP FETCH c_alunos INTO v_resultado; EXIT WHEN c_alunos%NOTFOUND; dbms_output.put_line('Aluno: ' || v_resultado.nrousp || ' - ' || v_resultado.nome || ' Nota: ' || v_resultado.nota); IF v_resultado.nota = 4.99 THEN UPDATE lbd08_matricula SET nota = 5.0 WHERE CURRENT OF c_alunos; /*para update ou delete*/ /*CURRENT OF se refere necessariamente a um único registro*/ /*o uso é vinculado a cursores FOR UPDATE OF para update e delete*/ END IF; END LOOP; COMMIT; /*Release FOR UPDATE records*/ CLOSE c_alunos; END; Atualizar na tabela a linha correspondente à linha atual do cursor => deve ser declarado como FOR UPDATE e a atualização será feita com base no indicador de linha atual (CURRENT OF) FOR UPDATE OF: Linhas de uma tabela são bloqueadas somente se a clausula FOR UPDATE OF referir-se a uma coluna daquela tabela. FOR UPDATE OF não requer nomes de colunas como parâmetros, no entanto, quando o cursor vier de uma junção, o uso dos nomes de coluna servem para identificar qual das tabelas envolvidas na junção terão seus registros bloqueados. “When querying multiple tables, you can use the FOR UPDATE clause to confine row locking to particular tables. Rows in a table are locked only if the FOR UPDATE OF clause refers to a column in that table. For example, the following query locks rows in the emp table but not in the dept table: DECLARE CURSOR c1 IS SELECT ename, dname FROM emp, dept WHERE emp.deptno = dept.deptno AND job = 'MANAGER' FOR UPDATE OF sal;” OBS: COLOCAR UM EXEMPLO COM JUNÇÃO NO UPDATE OF, PARA NÃO PARECER QUE PODE SER UMA TABELA SÓ!

31 Cursor Implícito - SQL Todas as instruções SQL são executadas dentro de uma área de contexto, então... existe um cursor implícito que aponta para essa área de contexto  cursor SQL PL/SQL implicitamente abre o cursor SQL, processa a instrução SQL e fecha o cursor E os cursores explícitos são utilizados para processar instruções SELECT que retornam mais de uma linha cursor SQL não é aberto ou fechado pelo programa.

32 Cursor Implícito - SQL Utilizado para processar as instruções: INSERT
UPDATE DELETE SELECT ... INTO SQL%FOUND: retorna TRUE caso o último comando SQL tenha afetado algum registro ou se o comando SELECT retornou algum registro; SQL%NOTFOUND: retorna TRUE caso o último comando SQL não tenha afetado nenhum registro. O SELECT será validado por exceptions (NO_DATA_FOUND), pois esse erro faz com que o controle passe imediatamente para a seção de tratamento de exceção do bloco, evitando a verificação em SQL%NOTFOUND. SQL%ROWCOUNT: retorna o numero de registros afetados pelo último comando SQL ou a última quantidade de registros retornada pelo último comando SELECT (deverá ser sempre 1, caso contrário a exception TOO_MANY_ROWS será disparada). SQL%ISOPEN: sempre retornará FALSE pois o Oracle sempre fecha o cursor após a execução do comando.

33 Exemplo – Cursor Implícito
DECLARE v_nota CONSTANT lbd08_matricula.nota%TYPE := 5.0; BEGIN UPDATE lbd08_matricula SET nota = v_nota WHERE nota > 3.0 AND nota < 6.0 AND coddisc = 'SSC0722'; IF SQL%FOUND /*cursor implícito associado ao UPADATE*/ THEN dbms_output.put_line(SQL%ROWCOUNT || ' alunos tiveram a nota alterada'); ELSE dbms_output.put_line('Nenhum aluno teve a nota alterada'); END IF; END;

34 Cursor Implícito - SQL INSERT/UPDATE/DELETE FOUND
TRUE: se o comando anterior alterou alguma tupla FALSE: caso contrário NOTFOUND (!FOUND) ROWCOUNT: nro de linhas alteradas pelo comando anterior ISOPEN sempre FALSE – propriedade útil apenas para cursores explícitos Os atributos têm diferenças de comportamento de acordo com o tipo de cursor. No implícito, o FOUND e NOTFOUND recebem true ou false se alguma tupla foi ou não afetada por uma operação de INSERT, DELETE, UPDATE ou SELECT INTO. Mas tem um detalhe: se numa operação de SELECT INTO nenhuma tupla for selecionada, o Oracle gera uma exceção de NO_DATA_FOUND, e já vai para bloco de exceptions.

35 Cursor Implícito - SQL SELECT INTO FOUND
TRUE: se o comando anterior retornou alguma tupla FALSE: caso contrário – no entanto a exceção NO_DATA_FOUND é lançada imediatamente NOTFOUND !FOUND ROWCOUNT: nro de tuplas retornadas pelo comando anterior se #tuplas = 0  ROWCOUNT == 0 exceção NO_DATA_FOUND - acessível apenas no bloco de exceção se #tuplas > 1 exceção TOO_MANY_ROWS - acessível apenas no bloco de exceção com ROWCOUNT = 1 se #tuplas = 1  ok, ROWCOUNT = 1 ISOPEN sempre FALSE – propriedade útil apenas para cursores explícitos Os atributos têm diferenças de comportamento de acordo com o tipo de cursor. No implícito, o FOUND e NOTFOUND recebem true ou false se alguma tupla foi ou não afetada por uma operação de INSERT, DELETE, UPDATE ou SELECT INTO. Mas tem um detalhe: se numa operação de SELECT INTO nenhuma tupla for selecionada, o Oracle gera uma exceção de NO_DATA_FOUND, e já vai para bloco de exceptions.

36 Cursor Implícito - SQL SELECT INTO FOUND TRUE: se o comando anterior retornou alguma tupla FALSE: caso contrário – no entanto a exceção NO_DATA_FOUND é lançada imediatamente NOTFOUND !FOUND ROWCOUNT: nro de tuplas retornadas pelo comando anterior se #tuplas = 0  ROWCOUNT == 0 exceção NO_DATA_FOUND - acessível apenas no bloco de exceção se #tuplas > 1 exceção TOO_MANY_ROWS - acessível apenas no bloco de exceção com ROWCOUNT = 1 se #tuplas = 1  ok, ROWCOUNT = 1 ISOPEN sempre FALSE – propriedade útil apenas para cursores explícitos Conclusão: o Oracle só permite a utilização de um cursor de seleção implícito caso ele selecione exatamente uma única tupla. Os atributos têm diferenças de comportamento de acordo com o tipo de cursor. No implícito, o FOUND e NOTFOUND recebem true ou false se alguma tupla foi ou não afetada por uma operação de INSERT, DELETE, UPDATE ou SELECT INTO. Mas tem um detalhe: se numa operação de SELECT INTO nenhuma tupla for selecionada, o Oracle gera uma exceção de NO_DATA_FOUND, e já vai para bloco de exceptions.

37 DECLARE v_aluno lbd01_vinculo_usp.nrousp%TYPE; v_nome lbd01_vinculo_usp.nome%TYPE; BEGIN v_nome := 'andre'; --SELECT nrousp INTO v_aluno FROM lbd01_vinculo_usp WHERE nome LIKE 'ANDRE'; --UPDATE lbd01_vinculo_usp SET nome = 'ANDRE' WHERE nome LIKE 'b%'; INSERT INTO lbd01_vinculo_usp VALUES(10,3,'adao','04/05/1978','05/08/1985','y'); IF SQL%FOUND THEN dbms_output.put_line('Alteracao TRUE'); ELSE dbms_output.put_line('Alteracao FALSE'); END IF; IF SQL%NOTFOUND THEN dbms_output.put_line('Sem alteracao TRUE ' || SQL%ROWCOUNT); dbms_output.put_line('Sem alteracao FALSE ' || SQL%ROWCOUNT); EXCEPTION WHEN OTHERS THEN dbms_output.put_line('Except: alteracao TRUE ' || SQL%ROWCOUNT); dbms_output.put_line('Except: alteracao FALSE ' || SQL%ROWCOUNT); dbms_output.put_line('Except: sem alteracao TRUE ' || SQL%ROWCOUNT); dbms_output.put_line('Except: sem alteracao FALSE ' || SQL%ROWCOUNT); END;

38 Esquema para os Exemplos de Cursor Implícito

39 Exemplo – Cursor Implícito
DECLARE v_cliente Cliente.Cd_Cliente%TYPE := 1; v_valor Nota_Fiscal.Vl_Total%Type; BEGIN SELECT Vl_Total INTO v_valor FROM Nota_Fiscal WHERE Cd_Cliente = v_cliente; IF v_valor > 0 THEN UPDATE Desconto_Concedido SET Vl_Desconto = Valor * 0.1, Dt_Atualizacao = sysdate WHERE Cd_Cliente = Aux_Cliente; IF SQL%NOTFOUND THEN INSERT INTO Desconto_Concedido (Cd_Cliente, Vl_Desconto, Dt_Atualizacao) VALUES (Aux_Cliente, Valor * 0.1, Sysdate) END IF; END; Para um determinado cliente, será verificado o valor total de suas compras. Se esse valor for maior do que 0 e caso o cliente ainda não tenha registro na tabela de DESCONTO_CONCEDIDO, um registro será incluído para ele. Do contrário, seu registro será apenas alterado. TEM ERRO!!!!

40 Exemplo – Cursor Implícito
DECLARE Vendas Number(5); Cursor Cur_Produtos IS SELECT Cd_Produto, Vl_Custo_Medio FROM Produto FOR UPDATE OF Vl_Custo_Medio; BEGIN FOR Reg_Produtos IN Cur_Produtos LOOP SELECT Count (*) INTO Vendas FROM Item_Nota_Fiscal WHERE Cd_Produto = Reg_Produtos.Cd_Produto; IF Vendas < 4 THEN Dbms_Output.Put_line (‘Desconto para o produto ’|| Reg_Produtos.Cd_Produto); UPDATE Produto SET Vl_Custo_Medio = Vl_Custo_Medio * 0.95 WHERE CURRENT OF Cur_Produtos; IF SQL%NOTFOUND THEN Dbms_Output.Put_Line(‘Erro na atualização.’); END IF; ELSE Dbms_Output.Put_Line(‘Sem alteração no produto ’|| END; Para cada produto da tabela PRODUTO, será contado o número de notas em que ele foi vendido. Caso tenha sido vendido em menos de quatro notas, o preço deste produto receberá um desconto de 5%, informando se houver provlemas na alteração (nenhuma linha alterada). Os produtos que participarem em mais de três vendas terão seu código apresentado e a referência de que não tiveram desconto.

41 PL/SQL Manual de consulta: PL/SQL User’s Guide and Reference


Carregar ppt "PL/SQL (Procedural Language/Structured Query Language)"

Apresentações semelhantes


Anúncios Google