aula5 pl sql
TRANSCRIPT
1
Laboratório de Bases de Dados
Profa. Elaine Parros Machado de Sousa
Aula 5 – PL/SQL
PL/SQLPL/SQL combina flexibilidade da SQL com construções procedimentais de uma 3GL
estende SQL: variáveis e tiposestruturas de controleprocedimentos e funçõestipos de objeto e métodos
PL/SQLPL/SQL engine ⇒ tecnologia
compila e executa blocos PL/SQLpode ser instalado em:
servidor Oraclestored procedures e triggersblocos 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 OracleOracle FormsOracle Reports
PL/SQL Engine
Figura retirada de PL/SQL User’s Guide and Reference (Release 2 (9.2))
PL/SQL – Tráfego em Rede
SQL SQL SQL
Servidor de BD
Aplicação Cliente
SQL … SQL … SQL
Servidor de BD
Aplicação Cliente
Bloco PL/SQL
PL/SQLRecursos
estrutura em blocosvariáveis e tipostratamento de errosestruturas de controle
condicionaisrepetição
cursoresprocedimentos e funçõespacotescoleçõesconceitos OO
2
Princípios básicos PL/SQLPL/SQL não tem comandos de entrada e saída
Pacote UTL_FILE ⇒ ler/escrever arquivoPacote DBMS_OUTPUT ⇒ saída em tela
set serveroutput on; /*habilita saída*/begindbms_output.put_line('Hello World!');
end;
Princípios básicos PL/SQLEstrutura em 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/SQLExemplo
DECLARE v_count NUMBER;
BEGINSELECT count(*) INTO v_count FROM aluno; dbms_output.put_line('NAlunos = ' || v_count);
END;
DECLARE v_nome aluno.nome%TYPE;v_idade aluno.idade%TYPE;
BEGINSELECT nome, idade INTO v_nome, v_idade FROM aluno A
WHERE A.nusp = 555; dbms_output.put_line('Aluno '|| v_nome ||
', idade ' || v_idade); EXCEPTION
WHEN NO_DATA_FOUND THENdbms_output.put_line('Aluno não encontrado');
/*se nusp não fosse único...*/
WHEN TOO_MANY_ROWS THENdbms_output.put_line('Há mais de um aluno
com este NUSP'); END;
Princípios básicos PL/SQLEstruturas condicionais
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;
3
Princípios básicos PL/SQL
DECLARE v_count NUMBER;
BEGINSELECT COUNT(*) INTO v_count FROM matricula M
WHERE M.sigla = 'SCE179' andM.ano = EXTRACT (YEAR FROM SYSDATE) andM.numero = 2;
IF v_count < 70 THEN INSERT INTO matricula VALUES ('SCE179', 2, 222,
EXTRACT (YEAR FROM SYSDATE), NULL); ELSE dbms_output.put_line('Turma lotada');END IF;
END;
DECLARE v_count NUMBER;e_lotada EXCEPTION;
BEGINSELECT COUNT(*) into v_count FROM matricula M
WHERE M.sigla = 'SCE179' andM.ano = EXTRACT (YEAR FROM SYSDATE) andM.numero = 2;
IF v_count < 70 THEN INSERT INTO matricula VALUES ('SCE179', 2, 444,
EXTRACT (YEAR FROM SYSDATE), NULL); ELSE RAISE e_lotada; END IF;
EXCEPTION WHEN e_lotada
THEN dbms_output.put_line('Turma lotada');WHEN OTHERS
THEN dbms_output.put_line('Erro nro: ' || SQLCODE || '. Mensagem: ' || SQLERRM );
END;
Princípios básicos PL/SQL
Estruturas de RepetiçãoLOOP <instruções> EXIT WHEN <condição de parada> END LOOP;
WHILE <condição> LOOP <instruções>
END LOOP;FOR <contador> IN [REVERSE] <min>..<max> LOOP <instruções>
END LOOP;
ExemploDECLARE
v_disciplina Turma.Sigla%TYPE;v_nroAlunos Turma.NAlunos%TYPE;
BEGINv_disciplina := 'SCE103'; v_nroAlunos := 0;
/* insere 6 turmas na disciplina SCE103 */FOR nroTurma IN 1..6 LOOP
INSERT INTO Turma VALUES (v_disciplina, nroTurma, v_nroAlunos);
END LOOP;
EXCEPTION ....
END;
Cursores
Área de contextoárea de memória com informações de processamento de uma instruçãoinclui conjunto ativo – linhas retornadas por uma consulta
Cursorhandle para uma área de contexto (cursor NÃO é uma variável de memória)tipos:
implícitoexplícito
Cursores - ExemploDECLARECURSOR c1 IS SELECT empno, ename, job
FROM empWHERE deptno = 20;
Figura retirada de PL/SQL User’s Guide and Reference (Release 2 (9.2))
4
Cursor Explícito
Passos: declarar o cursorabrir o cursor
OPEN
buscar resultadosFETCH – retorna uma tupla por vez e avança para a próxima no conjunto ativo
fechar cursorCLOSE
Cursor Explícito
AtributosFOUNDNULL se ainda não houve nenhum FETCHTRUE se o último FETCH retornou uma tupla
FALSE caso contrário
NOTFOUNDISOPENROWCOUNT
nro de tuplas já lidas
Exemplo – Cursor ExplícitoDECLARE
v_alunos Aluno%ROWTYPE;CURSOR c_alunos IS SELECT * FROM Aluno;
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('Aluno: ' || v_alunos.nome ||
' NUSP: ' || v_alunos.nusp); END LOOP;
CLOSE c_alunos; /*fecha cursor*/
END;
DECLAREv_aluno Matricula.aluno%TYPE;v_nota Matricula.nota%TYPE;
CURSOR c_alunos IS SELECT aluno, nota FROM Matricula WHERE sigla='SCE524'AND ano=2006 FOR UPDATE OF nota;
/*bloqueio exclusivo de linhas*/BEGINOPEN c_alunos; LOOP
FETCH c_alunos INTO v_aluno, v_nota; EXIT WHEN c_alunos%NOTFOUND; dbms_output.put_line('Aluno: ' || v_aluno ||
' Nota: ' || v_nota);IF v_nota = 4.99 THENUPDATE Matricula
SET nota = 5.0WHERE CURRENT OF c_alunos; /*para update ou delete*/
END IF;END LOOP; CLOSE c_alunos;END;
Cursor ImplícitoTodas 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.
Cursor ImplícitoÉ utilizado para processar as instruções:
INSERTUPDATEDELETESELECT ... INTO
5
Cursor ImplícitoAtributos
FOUNDTRUE se o comando anterior afetou ou retornou alguma tupla
NOTFOUNDTRUE se o comando anterior não afetou nenhuma tuplanão faz sentido para SELECT – exceção NO DATA FOUNDé lançada primeiro
ISOPENsempre FALSE
ROWCOUNTnro de linhas afetadas ou retornadas pelo comando anteriorexceção TOO MANY ROWS se SELECT retornar mais de uma tupla
Exemplo – Cursor ImplícitoDECLARE
v_nota CONSTANT matricula.nota%TYPE := 5.0;BEGIN
UPDATE matricula SET nota = v_nota WHERE nota > 4.9 AND nota < 5.0
AND sigla LIKE '%179';
IF SQL%FOUNDTHEN 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;
DECLAREv_aluno Aluno.nusp%TYPE;v_nome Aluno.nome%TYPE;
BEGIN
v_nome := 'Juliana';
SELECT nusp INTO v_aluno FROM Aluno WHERE nome = v_nome;
IF SQL%NOTFOUND /*teste SQL%NOTFOUND sem sentido aqui!!!*/THEN dbms_output.put_line('SQL%NOTFOUND é verdadeiro');ELSE DELETE FROM matricula WHERE aluno = v_aluno;
dbms_output.put_line(SQL%ROWCOUNT || ' matrículas de ' || v_nome || ' foram removidas');
END IF;
EXCEPTIONWHEN NO_DATA_FOUND THEN
dbms_output.put_line('Aluno não encontrado');WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('Há mais de um aluno com o nome ' || v_nome);
END;
PL/SQLManual de consulta:
PL/SQLUser’s Guide and Reference