PL/SQL (Procedural Language/Structured Query Language)

Slides:



Advertisements
Apresentações semelhantes
III – Oracle 9i Coleções.
Advertisements

Instituto de Computação - UFF Drinking Philosophers Algoritmos Distribuídos Professora: Lúcia Drummond.
Gerenciamento de Dados e Informação Estudo de caso – PL/SQL
ADO.NET (cont.). 1 Acesso a Bases de DadosADO.NET Namespace System.Data Modos de aceder à informação OLE DB – namespace System.Data.OleDb SQL - namespace.
Triggers Marilde Santos.
Sequences Marilde Santos. O que são Sequences? Valores sequenciais podem ser gerados automaticamente pelo Oracle com o uso de sequences. A sequence gera.
Manipulação de Arquivos de Dados
Java: Comandos Básicos
SQL Exercícios de Revisão Profa. Sandra de Amo Programa de Pós-graduação em Ciência da Computação – UFU
1 A Linguagem SQL Todo Banco de Dados apresenta uma Linguagem para definição e uma para manipulação de dados. Com relação aos Bancos de Dados Relacionais,
Prof. José Fernando Rodrigues Júnior Pacotes Material original: Profa. Elaine Parros Machado de Sousa SCC Bancos de Dados e Suas Aplicações.
SCC Bancos de Dados e Suas Aplicações
SCC Bancos de Dados e Suas Aplicações
SCC Bancos de Dados e Suas Aplicações
Procedimentos e Funções
SCC Bancos de Dados e Suas Aplicações
Ronaldo Celso Messias Correia
Html5- Desenvolvendo Aplicações. Html5- Introdução a SQL Métodos OpenDatabase (utilizado para criar ou abrir uma Base de Dados); Transaction (permite.
GRAFOS. Motivação Muitas aplicações em computação necessitam considerar conjunto de conexões entre pares de objetos: –Existe um caminho para ir de um.
FORTRAN 90 Denise Yumi Takamura.
SQL Procedural Junho/2006.
SQL procedural – parte 2.
Subconsultas em SQL. Subconsulta Estrutura geral SELECT.... FROM.... WHERE [at] OPERADOR ( SELECT... FROM... [WHERE... ]) Declaração SELECT localizada.
BDOO. Modelos tradicionais (relacional, rede e hierárquico) : aplicações tradicionais Novas aplicações para : Sistemas CAD Manufatura Experimentos científicos.
Funções de Linha 17/04/06. Funções de Linha Gerar ou construir novo valor não existente na tabela inicial. Valor construído a partir de dados de uma ou.
Introdução à Consulta 24/3/06. Categorias de comandos DDL : estruturação de objetos de BD Ex. create table, drop index, alter table... DML: manipulação.
Funções de Linha 24/04/06. Funções de Linha Gerar ou construir novo valor não existente na tabela inicial. Valor construído a partir de dados de uma ou.
SQL-3. Novo contexto e necessidade de : Manipular imagens Outros tipos de dados além de texto e números Recuperação de dados mais complexos Níveis distintos.
Objeto de BD: visão Há 2 tipos de tabelas Tabela base
Sintaxe de Fortran 25/abril/2006. Comandos Fortran PROGRAM PRINT READ STOP END.
Sql-3 ( final ).
Teste Estrutural de Software
Banco de Dados Geográficos
UNIVERSIDADE FEDERAL DE SANTA CATARINA PPGEP - Jornalismo On-line
Agregado Homogêneo e Heterogêneo
Formação de Administradores de Redes Linux LPI – level 1 SENAC TI Fernando Costa SQL (Structure Query Language)
Organização de Sistemas de Computadores
Desempenho A rápida taxa de melhoria na tecnologia de computadores veio em decorrência de dois fatores: avanços na tecnologia utilizada na construção.
Laboratório de Programação Prof. Oscar Luiz Monteiro de Farias
Tecnologia para Web JavaScript Enrique Pimentel Leite de Oliveira
LINGUAGENS DE PROGRAMAÇÃO
Sistemas de Informação Prof. Me. Everton C. Tetila Modelo de dados relacional Banco de Dados I.
Stored Procedure, Function and Trigger
Introdução Ciência da Computação estudo de algoritmos –ÊNFASE ao estudo de DADOS armazenamento manipulação refinamento (a partir de dados cru) estrutura.
Linguagem de Banco de Dados - SQL
Transporte Escolar Fluvial
Microsoft SQL Server 2008 SPARSE. Ambiente de teste Uma tabela é criada com 3 campos: CREATE TABLE [dbo].[Cliente_com_campos_basicos] ( [IdCliente] int.
Usando Java no Oracle Por Edson Almeida Junior
Prof. Eduardo Mantovani Prof. Fábio de P. Santos AES 2007.
WEKA. Roteiro Introdução Conceitos Exemplos práticos Chamada ao aplicativo.
INPE / CAP-315 Airam J. Preto, Celso L. Mendes Aula 30 (1) Empacotamento de Dados em MPI Tópicos: Buffer de Mensagem Empacotamento/Desempacotamento.
PL/SQL, Procedures e Funções
Monitoria GDI Aula Prática
Equipe de monitoria Aula prática 3.  Caso de estudo  Igualando situações  Cursor  Function  Procedure  Trigger  Package  Surpresa...
Primeira aula de PL/SQL Parte II
Oracle 9i: SQL e PL/SQL Bruno Celso Cunha de Freitas
Funções ou procedures Professor Esp. Diego André Sant’Ana
Cursor Professor Esp. Diego André Sant’Ana
III – Oracle 10g Coleções. Introdução Coleção: formada de objetos do mesmo tipo, cada um com um índice (posição) único dentro da coleção –NESTED TABLE.
Com coleções, cursor não é mais necessário
RT-EXPERT Artis Corp. C calling program RTSUB [rule set subroutine] RTSUB [rule set subroutine] RTSUB [rule set subroutine]... DSL Decision Support Language.
Monitoria GDI Aula Prática
Triggers (Gatilhos) Professor Esp. Diego André Sant’Ana
Aula 13 - Triggers. Triggers no SGBD Postgres  Os Triggers (Gatilhos) são funções preparadas para serem disparadas no caso de alguma alteração ocorrer.
Banco de Dados II Prof: Márcio Soussa Curso de Sistemas de Informação Faculdades Jorge Amado.
Transações George Azevedo da Silva José Antônio da Cunha.
Recursos de Programação
BANCO DE DADOS Araújo Lima Out / 2017 Araújo.
BANCO DE DADOS Araújo Lima Outubro / 2017 Araújo.
PL/SQL Triggers e Procedures
Transcrição da apresentação:

PL/SQL (Procedural Language/Structured Query Language) SCC0141 - 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

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

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

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

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

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

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

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

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

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;

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

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;

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

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

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

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

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;

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.

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

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”

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”

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

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

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

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

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

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

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

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Ó!

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Ó!

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.

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.

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;

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.

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.

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.

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;

Esquema para os Exemplos de Cursor Implícito

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

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.

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