PLSQL
PLSQL
PLSQL
BASE DE DADOS 1
O docente:
Hélder MC Muianga
[email protected]
(+258) 82-4727160
Programação em
PL/SQL
1
UEM
Sumário do Curso DMI
UEM
Objectivos do curso DMI
2
UEM
Conteúdo DMI
Introdução ao PL/SQL
Sumário de PL/SQL
Vantagem de PL/SQL
Declaração de variáveis de PL/SQL
Norma nomeada
Declaração de tipo escalar
Declaração de tipo %TYPE
Estrutura de Blocos PL/SQL
DECLARE, BEGIN, EXCEPTION e END
Interacção com servidor de Oracle
Uso SQL no ambiente de PL/SQL
Conceito de CURSOR
UEM
Conteúdo “cont.” DMI
Estruturas de controlo
IF, CASE, LOOP, WHILE e FOR
Tipos de dados
%ROWTYPE
INDEX BY
Uso de cursor explícito
Declaração de CURSOR
Uso de CURSOR explícito
Uso de excepção
Tipo de excepção
Função que devolve excepção
Combinação de PL/SQL com outras linguagens (VB, Java)
3
UEM
Objectivos DMI
UEM
Questão 1 DMI
empregado departamento 8
4
UEM
O que é PL/SQL DMI
PL/SQL
Procedural Language extension to SQL
Extensão de Linguagem Procedural para SQL
É linguagem padrão da Oracle para acesso a
dados numa BD relacional.
No seu processamento integra código SQL
IF… THEN … SQL PL/SQL
ELSE … SELECT … IF … THEN
END IF; FROM …; UPDATE …;
LOOP … + UPDATE …;
= ELSE …
END LOOP; INSERT …;
END IF; 9
UEM
O que é PL/SQL (Cont.) DMI
PL/SQL:
Define uma estrutura em bloco para execução de
códigos SQL. A manutenção do código é simples e
depende da correcta definição da estrutura
Define procedural constructs como:
Variáveis, constantes e tipos
Estruturas de controle tais como: declarações condicionais
e ciclos
Programas reusáveis que são escritos apenas uma única
vez e executados várias vezes.
Orientado a objectos
10
5
UEM
Porquê PL/SQL? DMI
Existem alguns comandos básicos em SQL que podemos usar para manipular
dados:
Exemplo:
Select empno, ename, deptno, sal from emp;
11
UEM
Porquê PL/SQL (Cont.) DMI
6
UEM
Ambiente de PL/SQL DMI
Execução de Servidor de Oracle Execução de Ferramentas
Oracle Forms
Bloco
SQL *Plus ORACLE Bloco Mota
PL/SQL
de PL/SQL de PL/SQL
13
* Ferramentas : Oracle Forms, Oracle Report
UEM
Vantagens do PL/SQL DMI
7
Vantagens do PL/SQL UEM
(Cont.) DMI
SQL1
SQL2
SQL 1
IF … THEN
SQL 2 SQL 3
Resultado ORACLE SQL4 ORACLE
SQL 3 ELSE
SQL 4 SQL5
END IF;
Várias vezes
Uma vez
15
8
UEM
Estrutura do Bloco PL/SQL DMI
Um bloco PL/SQL é composto pelas secções de:
1. Declaração (DECLARE)
2. Execução (BEGIN … END)
3. Excepção (EXCEPTION)
Sintaxe
[DECLARE] Opcional
Variáveis, cursores, excepções definidas pelo usuário
BEGIN Obrigatório
Declarações SQL, Declarações PL/SQL
[EXCEPTION] Opcional
Acções a levar a cabo caso ocorra um erro
END; Obrigatório
17
UEM
Secções dum Bloco PL/SQL DMI
Declaração
Começa com a palavra DECLARE e termina quando a secção de execução
começa
É opcional
Contém declaração de variáveis, constantes, cursor e excepção definidas
pelas usuário
Execução
Começa com a palavra BEGIN e termina com a palavra END seguido de
ponto-e-vírgula (;)
Secção obrigatória
Contém SQL, estruturas de controle e secção de excepção e pode ainda
conterb muitos outros blocos PL/SQL
Excepção
Esta aninhada na secção de Execução e começa com a palavra
EXCEPTION
É opcional
Quando ocorre um erro na secção de execução, nesta secção são levadas
a cabo acções específicas
18
9
UEM
Tipo de Blocos DMI
UEM
Tipo de Blocos (cont.) DMI
Anónimo
É um bloco sem nome
Declarado num ponto da aplicação onde vai ser executado e é
compilado sempre que a aplicação for executada. Estes blocos
não são armazenados na BD. São enviados ao executor de
declarações PL/SQL no momento da execução.
Subprogramas
Procedimento
Tem nome
Pode-se indicar valor retornado, este valor é mudado no
procedimento
Função
Tem nome e valor retornado
É obrigatório indicar o valor retornado.
20
10
UEM
Tipo de Programas DMI
21
11
UEM
Uso de iSQL*Plus DMI
23
UEM
DMI
Criação Dum Bloco Anónimo
Digite o bloco anónimo no Workspace do
iSQL*Plus
24
12
Execução Dum Bloco UEM
Anónimo DMI
25
UEM
Saída Dum Bloco PL/SQL DMI
26
13
Saída Dum Bloco UEM
PL/SQL (cont.) DMI
|| sinal de concatenação de
caracteres
27
UEM
Armazenamento de Script DMI
28
14
UEM
Comando SET DMI
UEM
PL/SQL Developer DMI
Acrescente
esta
declaração
30
15
UEM
Exemplos DMI
31
UEM
Objectivos DMI
32
16
UEM
Sumário DMI
UEM
Questão 2 DMI
17
UEM
Uso de Variáveis DMI
SELECT
ename,
Alberto emp_nome
deptno
INTO
emp_nome,
emp_deptno
FROM… 10 emp_deptn
35
o
UEM
Identificadores DMI
36
18
UEM
Identificadores VS Variáveis DMI
Variáveis são:
Declaradas e inicializadas na secção de
declaração
Usadas e atribuídas novos valores na secção de
execução
Passadas como parâmentros aos subprogramas
PL/SQL
Usadas para armazenar o resultado da saída
dum subprograma PL/SQL
Podem ser usadas para armazenar o resultado
devolvido por uma função
38
19
Declaração e Inicialização de UEM
Variáveis PL/SQL DMI
Sintaxe
Identificador [CONSTANT] tipo_de_dado [NOT NULL]
[:= | DEFAULT expr];
Exemplos
DECLARE
emp_data DATE;
emp_dno NUMBER(2) NOT NULL := 10;
location VARCHAR(13) := ‘Atlanta’;
c_comm CONSTANT NUMBER := 1400;
39
SET SERVEROUTPUT ON
DECLARE
Nome VARCHAR2(20);
BEGIN
DBMS_OUTPUT.PUT_LINE('O Meu Nome é ' ||
Nome);
Nome := ‘ALBERTO’;
DBMS_OUTPUT.PUT_LINE('O Meu Nome é ' ||
Nome);
END;
/ 40
20
Declaração e Inicialização UEM
de Variáveis PL/SQL (cont.) DMI
SET SERVEROUTPUT ON
DECLARE
Nome VARCHAR2(20) := ‘ALBERTO’;
BEGIN
Nome := ‘JOAO’;
DBMS_OUTPUT.PUT_LINE('O Meu Nome
é ' || Nome);
END;
/
41
SET SERVEROUTPUT ON
DECLARE
event1 VARCHAR2(15);
event2 VARCHAR2(15);
BEGIN
event1:=q’!Father’s day!’;
event2:=q’[Mother’s day]’;
DBMS_OUTPUT.PUT_LINE(‘3rd Sunday in June is ’||event1);
DBMS_OUTPUT.PUT_LINE(‘2nd Sunday in May is ’||event2);
END;
/ 42
21
UEM
Tipos de Variáveis DMI
• Variáveis PL/SQL:
• Escalares
• Armazenam valores singulares
• Compostas
• Um registo e uma tabela são exemplos de variáveis compostas
• Referência
• Armazenam ponteiros, que apontam para o local de armazenamento
de dados
• Large Objects (LOB)
• Armazenam valores denominados alocadores, que especificam a
localização de objectos de grande porte (como imagens gráficas).
• Variáveis Não-PL/SQL:
• Variáveis de ambiente
43
UEM
Questão 3 DMI
Agora já sabemos:
Que PL/SQL usa variáveis
Pretendemos declarar variáveis como:
1. 123_sal
2. sal_123
3. select#SMITH
4. abcdefg123456789012345678901234567890
5. END
Será possível usar estas variáveis?
44
22
Directrizes Para Declaração e UEM
Inicialização de Variáveis PL/SQL DMI
45
46
23
UEM
Questão 4 DMI
47
UEM
Tipos de Variáveis DMI
Escalar
NUMBER
VARCHAR2
DATE
BOOLEAN
Composto
%ROWTYPE
INDEX BY
VARRAY
Referência
CURSOR
Objectos grandes (LOB)
BLOB
CLOB
BFILE 48
24
Tipo de Dados Escalar UEM
DMI
CHAR [(comprimento_máximo)]
VARCHAR2 (comprimento_máximo)
LONG
LONG RAW
NUMBER [(precisão, escala)]
BINARY_INTEGER
PLS_INTEGER
BOOLEAN
BINARY_FLOAT
BINARY_DOUBLE
DATE
TIMESTAMP[(precisão)]
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH LOCAL TIME ZONE
INTERVAL YEAR TO MONTH
INTERVAL DAY TO SECOND
49
Exemplo:
DECLARE
emp_trabalho VARCHAR2(9);
contador BINARY_NUMBER :=0
dept_total_sal NUMBER(9,2) :=0;
data_compra DATE := SYSDATE +7;
c_taxa CONSTANT NUMBER(3,2) :=8.25;
valido BOOLEAN NOT NULL :=TRUE;
…
50
25
UEM
Questão 5 DMI
51
UEM
Atributo %TYPE DMI
Atributo %TYPE
É usado para declarar um variável de acordo:
Com a definição duma certa coluna na BD
Com a declaração de uma outra variável
É prefixado com:
A tabela e coluna da BD
O nome da variável declarada
52
26
Declaração de Variáveis UEM
Usando Atributo %TYPE DMI
Sintaxe
Identificador tabela.nome_de_coluna%TYPE;
Exemplos
nome empregado.enome%TYPE;
idade empregado.idade%TYPE;
Idade_media idade%TYPE :=2000;
53
27
UEM
Variáveis de Ambiente DMI
55
Exemplo:
VARIABLE resultado NUMBER
BEGIN
SELECT (sal*12) + NVL(comm,0) INTO :resultado
FROM emp
WHERE empno=7788;
END;
/
PRINT resultado
56
28
Imprimindo Variáveis de UEM
Ambiente DMI
Exemplo:
VARIABLE emp_salario NUMBER
BEGIN
SELECT sal INTO :emp_salario FROM emp WHERE empno=7788;
END;
/
PRINT emp_salario
SELECT pnome, apelido FROM emp WHERE sal=:emp_salario;
57
Exemplo:
VARIABLE emp_salario NUMBER
SET AUTOPRINT ON
BEGIN
SELECT sal INTO :emp_salario
FROM emp
WHERE empno=7788;
END;
/
58
29
UEM
Variáveis de Substituição DMI
60
30
Solicitando Variáveis de UEM
Substituição DMI
SET VERIFY OFF
VARIABLE emp_salario NUMBER
ACCEPT emp_numero PROMPT ‘Introduza um valor valido para o número do
empregado: ’
SET AUTOPRINT ON
DECLARE
emp_no NUMBER(6):= &emp_numero;
BEGIN
SELECT sal INTO :emp_salario
FROM emp
WHERE empno=emp_no;
END;
/
61
Exemplo:
SET VERIFY OFF
SET SERVEROUTPUT ON
DEFINE emp_apelido = 'SMITH'
DECLARE
salsal NUMBER;
BEGIN
SELECT sal INTO salsal
FROM emp
WHERE ename='&emp_apelido';
DBMS_OUTPUT.PUT_LINE(salsal);
END;
/ 62
31
UEM
Questão 6 DMI
empno
d_no SELECT empno, ename, sal
FROM emp enome
WHERE deptno=d_no; sal
d_no SELECT *
FROM emp
63
WHERE deptno=d_no;
UEM
Tipo de Dados Compostos DMI
64
32
UEM
Questão 7 DMI
65
UEM
Letra Maiúscula e Minúscula DMI
66
33
UEM
Objectivos DMI
67
Unidades léxicas:
São uma sequência de caracteres incluindo letras,
dígitos, espaços, símbolos
Podem ser classificados como sendo:
Identificadores
Delimitadores
“ ; ”, “ + ”, “ := ”
68
34
Unidades léxicas em um UEM
Bloco de PL / SQL (Cont.) DMI
Literais
São alguns valores que são atribuídos a variáveis
Comentários
-- Para comentar numa linha
/* */ Para comentar em múltiplas linhas
69
UEM
Identificadores DMI
70
35
UEM
Delimitadores DMI
71
UEM
Literais DMI
72
36
Comentários Dentro do UEM
Código DMI
UEM
Questão 8 DMI
74
37
Exercícios UEM
1. Liste os identificadores válidos e não válidos entre os seguintes:
a)
b)
hoje
p_nome
DMI
c) today´s day
d) #numero
e) NUMBER#
f) numero5
g) Numero_total_de_dias_de_duracao_do_curso_de_bases_de_dados_Oracle_10g
2. Qual é a vantagem do uso do %TYPE
3. Examine os seguintes blocos. Corrija-o caso seja necessário para garantir que corra
sem problemas:
VARIABLE emp_salario NUMBER
SET AUTOPRINT ON
DECLARE
p_nome
BEGIN
SELECT sal INTO :emp_salario
FROM emp
WHERE empno=emp_numero;
END;
/
PRINT emp_salario
DECLARE
valor_inicial CONSTANT NUMBER(2);
BEGIN
SELECT empno, deptno
FROM emp
WHERE employee_id=valor_inicial; 75
END;
Exercícios UEM
DECLARE DMI
empregado_id NUMBER(2);
salario NUMBER(6,2);
BEGIN
SELECT sal int salario
FROM emp
WHERE empno=empregado_id;
END;
/
38
UEM
Funções SQL no PL/SQL DMI
77
UEM
Funções SQL no PL/SQL DMI
Exemplo
Obtém o comprimento de caracteres
tamanho INTEGER(5);
descricao VARCHAR2(70) := ‘Você pode usar este produto com
o seu rádio.’;
tamanho := LENGTH(descricao);
78
39
Conversão de Tipo de UEM
Dados DMI
79
Conversão implícita
data_de_trabalho DATE := ’01-MAY-2000’ ;
Conversão explícita
data_de_trabalho DATE :=
TO_DATE(’February 02, 2000’, ‘Month DD, YYYY’) ;
80
40
UEM
Blocos Aninhados DMI
81
82
41
Alcance e Visibilidade da UEM
Variável Num Bloco(cont.) DMI
O resultado
83
UEM
Qualificar Um Identificador DMI
42
UEM
Operadores no PL/SQL DMI
Lógico
Aritmética Similar ao SQL
Concatenação
Parênteses para controlar ordem de operações
Operador Operação
** Exponencial
+, - Identidade, negação
*, / Multiplicação, divisão
+, -, || Adição, Subtracção, Concatenação
=, <, >, <=, >=, <>, !=, ~=, ^=, Comparação
IS NOT NULL, LIKE, BETWEEN, IN
NOT Negação lógica
AND Conjunção
85
OR Disjunção
Exemplos
Incrementa o contador de loop
contador := contador + 1;
86
43
Notificação de Operador no UEM
PL/SQL DMI
87
UEM
Formas de Programação DMI
88
44
Alinhamento (Indentation) UEM
de Código DMI
89
UEM
Sumário DMI
90
45
Declarações de SQL no UEM
PL/SQL DMI
91
92
46
Retorno de dados no UEM
PL/SQL DMI
47
Manipulação de Dados UEM
Usando PL/SQL DMI
95
UEM
Inserção de Dados DMI
48
UEM
Actualização de Dados DMI
97
UEM
Eliminação de Dados DMI
98
49
UEM
Fusão de Linhas DMI
DECLARE
e_no emp.empno := 7999;
BEGIN
MERGE INTO emp_copiada c USING emp e
ON (e.empno=e_no)
WHEN MATCHED THEN
UPDATE SET c.ename = e,ename, c.sal=e.sal
WHEN NOT MATCHED THEN
INSERT VALUES(e.empno, e.ename, e.job, e.mgr, e.hiredate, e.sal,
e.comm, e.deptno);
END;
/ 99
UEM
Questão DMI
Variável
100
50
Como é que se retornam várias UEM
linhas no Bloco do PL/SQL DMI
101
UEM
Cursor de SQL DMI
SELECT (seleccionar)
FETCH (trazer)
102
51
UEM
Cursor de SQL DMI
UEM
Questão DMI
O Edson perguntou:
Eu quero saber qual foi o número de linha
executado (seleccionado, inserido, actualizado e
removido) pela declaração de SQL
Há alguma maneira de saber?
104
52
Atributos de Cursor SQL UEM
para cursores implícitos DMI
53
Atributos de Cursor SQL para UEM
cursores implícitos (cont. 2) DMI
Exemplo
SET SERVEROUTPUT ON
DECLARE
nome emp.ename%TYPE;
BEGIN
SELECT ename INTO nome FROM EMP WHERE empno=7788;
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT);
END;
/
107
UEM
Sumário DMI
108
54
UEM
Questão DMI
109
110
55
Diagrama de IF, CASE e UEM
LOOP DMI
IF CASE LOOP
Falso Falso
Condição Condição Condição
Valor 1 Valor 2 Valor 3
Verdadeiro Verdadeiro
Processo 1 Processo 3
111
UEM
Declaração IF DMI
56
UEM
Declarações simples de IF DMI
DECLARE
minha_idade NUMBER := 25;
BEGIN
IF minha_idade < 11 THEN
DBMS_OUTPUT.PUT_LINE(‘Eu sou criança.’); -- Não é executado
END IF;
END;
/
a) Minha_idade é 25
b) Condição sempre deve retornar Verdadeiro ou Falso ou Nulo
c) Nesta condição minha_idade é menor do que 11. O resultado da
proposição é falso
d) Neste caso, as declarações após o THEN não são executadas
O que deve ser alterado, para que as declarações sejam executadas?
113
SET SERVEROUTPUT ON
DECLARE
minha_idade NUMBER := 31;
BEGIN
IF minha_idade < 11 THEN
DBMS_OUTPUT.PUT_LINE(‘Eu sou criança.’); -- Não é executado
ELSE
DBMS_OUTPUT.PUT_LINE(‘Eu não sou criança!!!’);
END IF;
END;
/
57
UEM
Cláusula de IF ELSIF ELSE DMI
DECLARE
minha_idade NUMBER := 31;
BEGIN
IF minha_idade < 11 THEN
DBMS_OUTPUT.PUT_LINE(‘Eu sou criança.’);
ELSIF minha_idade < 25 THEN
DBMS_OUTPUT.PUT_LINE(‘Eu sou rapaz.’);
ELSIF minha_idade < 40 THEN
DBMS_OUTPUT.PUT_LINE(‘Eu sou meia-idade.’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Eu já tou a ficar velhinho’);
END IF;
END;
/
115
IF ELSIF ELSE é executado por ordem.
DECLARE
minha_idade NUMBER;
BEGIN
IF minha_idade < 11 THEN
DBMS_OUTPUT.PUT_LINE(‘Eu sou criança.’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Eu não sou criança!!!’);
END IF;
END;
/
58
UEM
Expressões de CASE DMI
UEM
Exemplo : CASE DMI
SET SERVEROUTPUT ON
SET VERIFY OFF
DECLARE
nivel CHAR(1) := UPPER('&nivel');
avaliacao VARCHAR2(20);
BEGIN
avaliacao :=
CASE nivel
WHEN 'A' THEN 'Excelente'
WHEN 'B' THEN 'Muito Bom'
WHEN 'C' THEN 'Bom'
ELSE 'Não existe esse nível ' || nivel
END;
DBMS_OUTPUT.PUT_LINE('Nível é ' || nivel || '. Avaliação é ' || avaliacao || '.');
END;
/
118
59
UEM
Exemplo : CASE Pesquisada DMI
SET SERVEROUTPUT ON
SET VERIFY OFF
DECLARE
nivel CHAR(1) := UPPER('&nivel');
avaliacao VARCHAR2(20);
BEGIN
avaliacao :=
CASE -- Não há variável de selecção (selector)
WHEN nivel= 'A' THEN 'Excelente'
WHEN nivel IN ('B', 'C') THEN 'Bom'
ELSE 'Não há esse nível ' || nivel
END;
DBMS_OUTPUT.PUT_LINE('Nível é ' || nivel || '. ' || avaliacao || '.');
END;
/
119
60
UEM
Tabelas de lógica DMI
NOT Resultado
TRUE FALSE
FALSE TRUE
121
NULL NULL
UEM
Condições Booleanas DMI
122
61
Controle de Repetição: UEM
Declarações de LOOP DMI
123
UEM
LOOP Básico DMI
Sintaxe
LOOP
Declaração1;
…
EXIT [WHEN condição];
END LOOP;
Exemplo
idade := 0;
LOOP
idade := idade + 1;
EXIT WHEN idade = 10;
END LOOP; 124
62
UEM
WHILE LOOP DMI
Exemplo
WHILE idade < 10 LOOP
idade := idade + 1;
END LOOP;
125
UEM
FOR LOOP DMI
Exemplo
FOR i IN 1..10 LOOP
INSERT INTO emp(empno) VALUES(i);
END LOOP; 126
63
UEM
Alinhando Repetições DMI
Exemplo
SET SERVEROUTPUT ON
DECLARE
BEGIN
FOR i IN 1..3 LOOP
DBMS_OUTPUT.PUT_LINE(i || ' ');
FOR j IN 1..5 LOOP
DBMS_OUTPUT.PUT_LINE(j);
END LOOP;
END LOOP;
END;
/
127
UEM
Sumário DMI
128
64
UEM
Questão DMI
129
UEM
Tipos de dados compostos DMI
Registros de PL/SQL
Colecções de PL/SQL
Tabelas de INDEX BY ou ordens associativas
Tabela agregada
VARRAY
130
65
UEM
Registros do PL/SQL DMI
Identificador nome_de_tipo;
Declaração de campo
Nome_de_campo { tipo_de_campo ou variável%TYPE
ou tabela.coluna%TYPE ou tabela%ROWTYPE}
[[NOT NULL] {:= ou DEFAULT} expr] 131
132
66
Estrutura de Registros de UEM
PL/SQL DMI
Exemplo
empno ename job
NUMBER(4) VARCHAR2(10)VARCHAR2(9)
UEM
Questão DMI
134
67
UEM
Atributo %ROWTYPE DMI
Sintaxe
DECLARE
identificador referência%ROWTYPE;
135
Exemplo: UEM
Atributo %ROWTYPE DMI
68
Inserção de Registros que UEM
Usam %ROWTYPE DMI
SET SERVEROUTPUT ON
SET VERIFY OFF
DEFINE empno=7369
DECLARE
reg_emp emp_aposentado%ROWTYPE;
BEGIN
SELECT * INTO reg_emp FROM emp_aposentado;
reg_emp. Leavedate := SYSDATE;
UPDATE emp_aposentado SET ROW = reg_emp
WHERE empno=&empno;
END;
/
SELECT * FROM emp_aposentado;
69
UEM
Questão DMI
140
70
UEM
Criando tabela de INDEX BY DMI
Sintaxe
TYPE nome_de_tipo IS TABLE OF
{tipo_de_coluna ou variável%TYPE ou tabela.coluna%TYPE} [NOT NULL]
ou tabela%ROWTYPE
[INDEX BY PLS_INTEGER ou BINARY_INTEGER ou VARCHAR2(tamanho)]
identificador tipo_de_nome;
PLS_INTEGER Escalar
142
71
Criação de tabela de INDEX UEM
BY DMI
DECLARE
TYPE tipo_tabela_ename IS TABLE OF emp.ename%TYPE
INDEX BY PLS_INTEGER; -- Declaração do tipo de variável
TYPE tipo_tabela_hiredate IS TABLE OF DATE
INDEX BY PLS_INTEGER; -- Declaração de tipo de variável
tabela_ename tipo_tabela_ename; -- Declaração de tabela ename
tabela_hiredate tipo_tabela_hiredate; -- Declaração de tabela hiradate
BEGIN
tabela_ename(1) := ‘CAMERON’;
tabela_hiredate(8) := SYSDATE + 7;
IF tabela_ename.EXISTS(1) THEN
INSERT INTO emp(empno, ename) VALUES(7999, tabela_ename(1));
END IF;
END;
/
143
M étodo Descrição
E XISTS(n) Retorna Verdadeiro se existe o n-elem ento na tabela de PL/SQL
COUNT Retorna o núm ero de elem entos contidos actualm ente na tabela de PL/SQL
FIRST Retorna prim eiro ou últim o núm ero de index na tabela de PL/SQL.
LAST Retorna NULL se a tabela de PL/SQL estiver vazia.
PRIOR(n) Retorna o núm ero de index que precede o index n na tabela de PL/SQL
NE XT(n) Retorna o núm ero de index que sucede ao index n na tabela de PL/SQL
DE LE TE DE LE TE rem ove todos os elem entos de tabela de PL/SQL
DE LE TE (n) rem ove elem ento n de tabela de PL/SQL
DE LE TE (m , n) rem ove todos os elem entos no intervalo m …n de tabela de
PL/SQL
144
72
Registros de Tabela de UEM
INDEX BY DMI
145
Tabela emp
empno ename job mgr sal deptno
73
Exemplo de Tabela de UEM
INDEX BY de Registros DMI
SET SERVEROUTPUT ON
DECLARE
TYPE tipo_tabela_emp IS TABLE OF emp%ROWTYPE
INDEX BY PLS_INTEGER; -- Declaração do tipo de ROWTYPE
a_minha_tabela_emp tipo_tabela_emp;
min_count := 7996;
max_count := 7999;
BEGIN
FOR i IN min_count..max_count LOOP
SELECT * INTO a_minha_tabela_emp(i) FROM emp WHERE empno=i;
END LOOP;
FOR i IN a_minha_tabela_emp.FIRST.. a_minha_tabela_emp.LAST LOOP
DBMS_OUTPUT.PUT_LINE(a_minha_tabela_emp(i).ename);
END LOOP;
END;
/
147
148
74
VARRAY: Variable-size UEM
arrays DMI
Exemplo:
TYPE tipo_varray_loc IS VARRAY(3) OF dept.loc%TYPE;
escritorios tipo_varray_loc;
149
UEM
Sumário DMI
150
75
UEM
Questão DMI
151
UEM
Cursores: O que são? DMI
152
76
UEM
Cursores Explícitos DMI
153
Declarar o cursor
Declara o cursor na secção declarativa do bloco PL/SQL
Abrir o cursor
A declaração OPEN executa a consulta e faz o bind de qualquer variável
que seja referenciada.
Buscar os dados do cursor
Depois de buscar os dados do cursor, testa-se o cursor para saber se ainda
há alguma linha. Se não há mais linhas para processar, então, deve-se
fechar o cursor
Fechar a cursor
A declaração CLOSE liberta o conjunto activo de linhas. Depois, é possível
reabrir a cursor para estabelecer o novo conjunto activo.
Não
77
Controlo de Cursores UEM
Explícitos (cont.) DMI
linha2 Indicador de
linha3 Cursor
linha4
linha1
3. fechar (CLOSE)
o Cursor
Indicador de
Cursor
155
UEM
Declaração do Cursor DMI
Sintaxe
CURSOR nome_cursor IS
declaração_SELECT;
Exemplos
DECLARE
CURSOR cursor_emp IS
SELECT empno, ename FROM emp
WHERE deptno=30;
DECLARE
eno NUMBER := 7788;
CURSOR cursor_emp IS
SELECT * FROM emp
WHERE empno=eno;
156
78
UEM
Abrir o Cursor DMI
Sintaxe
OPEN nome_cursor;
Exemplo
DECLARE
CURSOR cursor_emp IS
SELECT empno, ename FROM emp
WHERE deptno=30;
…
BEGIN
OPEN cursor_emp;
UEM
Buscando dados do Cursor DMI
SET SERVEROUTPUT ON
DECLARE
CURSOR cursor_emp IS
SELECT empno, ename FROM emp
WHERE deptno=30;
numero emp.empno%TYPE;
nome emp.ename%TYPE;
BEGIN
OPEN cursor_emp;
FETCH cursor_emp INTO numero, nome;
DBMS_OUTPUT.PUT_LINE(numero || ‘ ‘ || nome);
CLOSE cursor_emp;
END;
/
158
79
UEM
Fechando o Cursor DMI
SET SERVEROUTPUT ON
DECLARE
CURSOR cursor_emp IS
SELECT empno, ename FROM emp
WHERE deptno=30;
numero emp.empno%TYPE;
nome emp.ename%TYPE;
BEGIN
OPEN cursor_emp;
LOOP
FETCH cursor_emp INTO numero, nome;
EXIT WHEN cursor_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(numero || ‘ ‘ || nome);
END LOOP;
CLOSE cursor_emp;
END;
/
159
UEM
Cursores e Registos DMI
SET SERVEROUTPUT ON
DECLARE
CURSOR cursor_emp IS
SELECT empno, ename FROM emp
WHERE deptno=30;
registo_emp cursor_emp%ROWTYPE;
BEGIN
OPEN cursor_emp;
LOOP
FETCH cursor_emp INTO registro_emp;
EXIT WHEN cursor_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(registro_emp.enpno);
DBMS_OUTPUT.PUT_LINE(registro_emp.ename);
END LOOP;
CLOSE cursor_emp;
END;
/ 160
80
UEM
Cursor FOR Loops DMI
Sintaxe
FOR nome_registo IN nome_cursor LOOP
declaração1;
declaração2;
…
END LOOP;
UEM
Cursor FOR Loops (cont.) DMI
SET SERVEROUTPUT ON
DECLARE
CURSOR cursor_emp IS
SELECT empno, ename FROM emp
WHERE deptno=30;
/* Não precisa de declarar o registo na secção declarativa */
BEGIN
FOR registo_emp IN cursor_emp LOOP
DBMS_OUTPUT.PUT_LINE(registro_emp.empno
|| ‘ ‘ || registro_emp.ename);
END LOOP;
END;
/
162
81
UEM
O atributo %ISOPEN DMI
163
%ROWCOUNT
FETCH cursor_emp INTO empno, ename;
IF cursor_emp%ROWCOUNT <= 10 THEN
DBMS_OUTPUT.PUT_LINE(‘Agora há 10 linhas.’);
END IF;
%NOTFOUND
FETCH cursor_emp INTO empno, ename;
IF cursor_emp%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE(‘Não há linhas.’);
END IF;
164
82
Cursor FOR Loop usando UEM
subconsultas DMI
SET SERVEROUTPUT ON
BEGIN
FOR registro_emp IN (SELECT empno, ename, sal
FROM emp WHERE deptno = 30)
LOOP
DBMS_OUTPUT.PUT_LINE(registro_emp.empno
|| ‘ ’ || registro_emp.ename || ‘ ’ || registro_emp.sal);
END LOOP;
END;
/
165
UEM
Cursores com Parâmetros DMI
Sintaxe
CURSOR nome_cursor
[nome_parâmetro tipo_de_dados]
IS
declaração_select;
…
OPEN nome_cursor (valor_do_parâmetro);
166
83
Cursores com Parâmetros UEM
(Cont.) DMI
Exemplo:
SET SERVEROUTPUT ON
DECLARE
CURSOR cursor_emp (deptno NUMBER) IS
SELECT empno, ename
FROM emp
WHERE deptno=deptno;
dept_id NUMBER;
nome VARCHAR2(15);
BEGIN
OPEN cursor_emp (10); -- Primeira vez
…
CLOSE cursor_emp;
OPEN cursor_emp (20); -- Segunda vez
… 167
UEM
A Cláusula FOR UPDATE DMI
Sintaxe
SELECT …
FROM …
FOR UPDATE [OF referência_da_coluna] [NOWAIT | WAIT n]
168
84
A Cláusula FOR UPDATE UEM
(cont.) DMI
Exemplo
DECLARE
CURSOR cursor_emp IS
SELECT empno, ename FROM emp
WHERE deptno=30 FOR UPDATE OF sal NOWAIT;
169
Sintaxe
WHERE CURRENT OF cursor ;
85
UEM
Cursores com Subconsultas DMI
Exemplo
DECLARE
CURSOR meu_cursor IS
SELECT d.deptno, d.dname, e.empregados
FROM dept d, (SELECT deptno, COUNT(*) AS empregados
FROM emp
GROUP BY deptno) e
WHERE d.deptno = e.deptno(+);
171
UEM
Sumário: DMI
172
86
UEM
Questão DMI
Erro
173
UEM
Tratamento de Excepções DMI
Objectivos:
Definir excepções em PL/SQL
Reconhecer excepções não tratadas
Listar e usar diferentes tipos de excepções em
PL/SQL
Segurar erros não participados
Descrever o efeito da propagação de excepções em
blocos aninhados
Personalizar as mensagens de erro em PL/SQL
174
87
UEM
Caso de Erro DMI
Exemplo
SET SERVEROUTPUT ON
DECLARE
apelido VARCHAR2(15);
BEGIN
SELECT ename INTO apelido FROM emp WHERE sal=3000;
DBMS_OUTPUT.PUT_LINE('Nome de empregado que recebe
salário 3000 é ' || apelido);
END;
/
DECLARE
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows 175
ORA-06512: at line 4
UEM
Solução do Erro DMI
SET SERVEROUTPUT ON
DECLARE
apelido VARCHAR2(15);
BEGIN
SELECT ename INTO apelido FROM emp WHERE sal=3000;
DBMS_OUTPUT.PUT_LINE('Nome de empregado que recebe
salário 3000 é ' || apelido);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE(‘A sua declaração retornada várias
linhas. Considere o uso de CURSOR.’);
END;
/
88
Tratamento de Excepções UEM
em PL/SQL DMI
177
UEM
Tipos de Excepção DMI
89
UEM
Segurando Excepções DMI
Sintaxe
EXCEPTION
WHEN excepção1 [OR excepção2 …] THEN
declaração1;
declaração2;
[WHEN excepção3 [OR excepção4 …] THEN
declaração1;
declaração2;
…]
[WHEN OTHERS THEN
declaração1;
declaração2;
…]
179
180
90
UEM
Excepções Predefinidas DMI
1 ACCESS_INTO_NULL ORA-06530
2 CASE_NOT_FOUND ORA-06592
3 COLLECTION_IS_NULL ORA-06531
4 CURSOR_ALREADY_OPEN ORA-06511
5 DUP_VAL_ON_INDEX ORA-00001
6 INVALID_CURSOR ORA-01001
7 INVALID_NUMBER ORA-01722
8 LOGIN_DENIED ORA-01403
9 NO_DATA_FOUND ORA-01403
10 NOT_LOGGED_ON ORA-01012
11 PROGRAM_ERROR ORA-06501
12 ROWTYPE_MISMATCH ORA-06504
13 STORAGE_ERROR ORA-06500
14 SUBSCRIPT_BEYOND_COUNT ORA-06533
15 SUBSCRIPT_OUTSIDE_LIMIT ORA-06532
16 SYS_INVALID_ROWID ORA-01410
17 TIMEOUT_ON_RESOURCE ORA-00051
18 TOO_MANY_ROWS ORA-01422
181
19 VALUE_ERROR ORA-06502
20 ZERO_DIVIDE ORA-01476
UEM
Erros Não Predefinidos DMI
91
Segurando Excepções UEM
Definidas pelo Usuário DMI
DECLARE
dept_invalido EXCEPTION;
nome VARCHAR2 (20) := ‘LOGISTICA’;
deptnum NUMBER := 250;
BEGIN
UPDATE dept
SET dept_name = nome WHERE deptno = deptnum;
IF SQL%NOTFOUND THEN
RAISE dept_invalido;
END IF;
COMMIT;
EXCEPTION
WHEN dept_invalido THEN
DBMS_OUTPUT.PUT_LINE (‘Não existe departamento com esse ID’)
END;
/
183
O Procedimento UEM
RAISE_APPLICATION_ERROR DMI
Sintaxe:
raise_application_error (numero_erro, mensagem [,
{TRUE | FALSE}]);
É usado em dois locais distintos:
Secções executáveis;
Secções de excepção
Retorna as condições de erro ao usuário de um
modo consistente com os erros do servidor Oracle
184
92
RAISE_APPLICATION_ERROR UEM
(Cont) DMI
Secção executável:
BEGIN
...
DELETE FROM emp
WHERE mgr = v_mgr;
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR (-20202, ‘Número de gestor inválido’);
END IF;
....
Secção de excepção:
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR (-20201, ‘O gestor não é um empregado válido);
END;
/
185
UEM
Sumário: DMI
186
93
UEM
Exercícios (1) DMI
187
UEM
Exercícios (2) DMI
188
94
UEM
Soluções (1) DMI
2. Declare
emp_nome emp.ename%TYPE;
emp_sal emp.sal%TYPE:=&salario;
3. Begin
SELECT ename
INTO emp_nome
FROM emp
WHERE sal = emp_sal;
4. EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT into mensagens (msg) values (‘Nao existe empregado com esse salario: ’||’ –
‘||TO_CHAR(emp_sal));
…
189
UEM
Soluções (2) DMI
5. …
WHEN TOO_MANY_ROWS THEN
INSERT into mensagens (msg) values (‘Foi encontrado mais do que um registo com salario
de: ’||’ – ‘||TO_CHAR(emp_sal));
6. …
WHEN OTHERS THEN
INSERT into mensagens (msg) values (‘Foi encontrado um erro desconhecido’);
…
7. Select * from mensagens;
8. …
alter table mensagens add (total_registos NUMBER(3));
…
WHEN TOO_MANY_ROWS THEN
Select count(*) into num_linhas FROM emp WHERE sal=emp_sal;
INSERT into mensagens values (‘Foi encontrado mais do que um registo com salario de: ’||’ –
‘||TO_CHAR(emp_sal), num_linhas);
190
95
UEM
Questão DMI
PL/SQL
PL/SQL PL/SQL
ORACLE
PL/SQL ORACLE191
UEM
Procedimentos e Funções DMI
Objectivos:
Estabelecer a diferença entre blocos anónimos e
sub-programas
Criar um procedimento simples e invocá-lo a partir
dum bloco anónimo
Criar funções simples
Criar funções simples que aceitem um parâmetro
Estabelecer a diferença entre procedimentos e
funções
192
96
UEM
Procedimentos e Funções DMI
97
UEM
Procedimento (Cont.) DMI
Exemplo
CREATE OR REPLACE PROCEDURE add_dept IS
d_no dept.deptno%TYPE;
nome dept.dname%TYPE;
BEGIN
d_no := 60;
nome := 'MICTI';
INSERT INTO dept (deptno, dname)
VALUES(d_no, nome);
DBMS_OUTPUT.PUT_LINE(‘Inseridas ' || SQL%ROWCOUNT || ' linha(s).');
END;
/
SHOW ERRORS
195
UEM
Invocação de Procedimento DMI
Exemplo
BEGIN
add_dept;
END;
/
Exemplo 2
EXECUTE add_dept;
196
98
UEM
Função DMI
Sintaxe
CREATE [OR REPLACE] FUNCTION nome_função
[(argumento1 IN tipo_de_dados1,
argumento2 IN tipo_de_dados2,
…)]
RETURN tipo_de_dado
IS | AS
corpo_função;
197
UEM
Função DMI
99
UEM
Invocação de Função DMI
Exemplo
SET SERVEROUTPUT ON
BEGIN
IF (check_sal IS NULL) THEN
DBMS_OUTPUT.PUT_LINE(‘Excepção.’);
ELSIF (check_sal) THEN
DBMS_OUTPUT.PUT_LINE(‘Salário > médio’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Salário < médio’);
END IF;
END;
/
199
200
100
Invocação da Função com o UEM
Parâmetro DMI
SET SERVEROUTPUT ON
BEGIN
IF (check_sal(7788) IS NULL) THEN
DBMS_OUTPUT.PUT_LINE(‘Excepção.’);
ELSIF (check_sal(7788)) THEN
DBMS_OUTPUT.PUT_LINE(‘Salário > médio’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Salário < médio’);
END IF;
END;
/
201
UEM
Função Aninhada DMI
SET SERVEROUTPUT ON
CREATE OR REPLACE PROCEDURE test01(e_no IN emp.empno%TYPE) IS
e_nome emp.ename%TYPE;
FUNCTION caracter (carac IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN TO_CHAR(SYSDATE || ' ****** ' || carac || ' ****** ');
END;
BEGIN
DBMS_OUTPUT.PUT_LINE(caracter('START'));
SELECT ename INTO e_nome FROM emp WHERE empno=e_no;
DBMS_OUTPUT.PUT_LINE(caracter(e_nome));
DBMS_OUTPUT.PUT_LINE(caracter('END'));
END;
/
SHOW ERRORS
EXECUTE test01(7788);
202
101
UEM
Sumário: DMI
203
UEM
Packages DMI
Package
Procedimento Procedimento Procedimento Função
204
102
UEM
Tipo de Packages DMI
Package Normal
Tem declarações de subprogramas que já
existem
Variáveis públicas acedidas pelo programa exterior
Subprogramas que já existem
Package Body
Tem a parte de Body
Body
Variáveis privadas
Subprogramas
205
UEM
Package Normal DMI
Sintaxe
CREATE [OR REPLACE] PACKAGE {nome_de_package}
IS ou AS
tipo público e declarações de variáveis;
subprograma especificações;
END [nome_de_package];
Exemplo
CREATE OR REPLACE PACKAGE sal_pkg IS
std_sal NUMBER := 1000; -- inicializado por 1000
PROCEDURE calcula_sal(sal_novo NUMBER);
END [nome_de_package];
206
103
UEM
Package Body DMI
104
Remoção de Packages e UEM
Body DMI
209
UEM
Triggers DMI
O trigger:
É bloco de PL/SQL ou procedimento de PL/SQL associado
a uma tabela, view, schema ou base de dados
É executado implicitamente quando um evento particular
ocorre
Tipos:
Trigger de aplicação: é executado quando evento acontece
com uma aplicação particular
Trigger de BD: é executado quando evento de dados
(como DML) ou evento de sistema (como logon ou
shutdown) ocorre num schema ou BD
210
105
UEM
Sintaxe de Trigger de DML DMI
211
Eliminar trigger
DROP TRIGGER nome_de_trigger ;
Activar trigger
ALTER TRIGGER nome_de_trigger ENABLE;
Desactivar trigger
ALTER TRIGGER nome_de_trigger DISABLE;
212
106
UEM
Exemplo de Trigger de DML DMI
213
214
107
ROW trigger de DML: UEM
NEW e OLD DMI
INSERT INTO emp (empno, ename, job, sal)UPDATE emp SET sal=1000
VALUES(7999, ‘KAZUKI’, ‘CLERK’, 5000); WHERE sal > 1000;
UPDATE :NEW.sal
:NEW.job
:OLD.sal
215
216
108
UEM
Trigger de BD DMI
Sintaxe
CREATE [OR REPLACE] TRIGGER nome_de_trigger
timing
[evento1 [OR evento2 OR …]]
ON {DATABASE ou SCHEMA}
conteúdo_de_trigger
UEM
Exemplo de Trigger de BD DMI
109
UEM
Exercício (1) DMI
SET SERVEROUTPUT ON
DECLARE
hoje DATE:=SYSDATE;
amanha hoje%TYPE;
BEGIN
amanha:=hoje +1;
DBMS_OUTPUT.PUT_LINE(' Alo Mundo ');
DBMS_OUTPUT.PUT_LINE('Hoje é : '|| hoje);
DBMS_OUTPUT.PUT_LINE('Amanhã será : ' || amanha);
END;
UEM
Exercício (2) DMI
220
110
UEM
Exercício (3) DMI
221
UEM
Soluções (1) DMI
SET SERVEROUTPUT ON
SHOW ERRORS
BEGIN
amanha:=hoje+1;
DBMS_OUTPUT.PUT_LINE('Alo ' || nome);
DBMS_OUTPUT.PUT_LINE('Hoje é ' || hoje);
DBMS_OUTPUT.PUT_LINE('Amanhã será ' || amanha);
END;
BEGIN
cumprimento('Dercio');
END;
222
111
UEM
Soluções (2) DMI
SHOW ERRORS
BEGIN
if verifica_dept(40) then
DBMS_OUTPUT.PUT_LINE ('O departamento existe');
else
DBMS_OUTPUT.PUT_LINE ('O departamento nao existe');
end if; 223
END;
UEM
Soluções (3) DMI
SHOW ERRORS
CREATE OR REPLACE TRIGGER upSalTrig
BEFORE UPDATE OF sal ON emp
FOR EACH ROW
DECLARE
deptSales emp.deptno%TYPE;
deptOperations emp.deptno%TYPE;
BEGIN
112
UEM
Questão DMI
Chamar Procedimento
ou
ORACLE
Retornar Função
225
UEM
Chamado por VB.Net DMI
Sequência de Processo
Configurar Conectar Criar Acrescentar
Serviço, usuário BD por oo4o Declaração Parâmetro
226
113
A Parte de Conexão UEM
DMI
dbname = "orcl"
cnuser = "oracle0/micti"
Set OraSession =
CreateObject("OracleInProcServer.XOraSession")
if err <> 0 then
MsgBox “Não pode conectar" & chr(10) & “Erro de oo4o"
end
end if
Set OraDatabase = OraSession.OpenDatabase(dbname,
cnuser, ORADB_DEFAULT)
if err <> 0 then
MsgBox “Não pode conectar a BD Oracle" & chr(10) & err & ":
" & error
end
end if 227
UEM
Criação de Parâmetro DMI
228
114
UEM
Chamado por Java DMI
Sequência de processo
Carregar Conectar Criar
JDBC Drivers Base de Dados Declaração
Configurar
Inicialização
Fechar Fechar Executar
Conexão Declaração Declaração
229
UEM
A Parte de Declaração DMI
230
115
UEM
A Parte de Conexão DMI
Class.forName("oracle.jdbc.driver.OracleDriver
");
System.out.println(“Carregou JDBC API");
conn = DriverManager.getConnection
("jdbc:oracle:thin:@lc08:1521:ORCL",
“oracle0", “micti");
System.out.println(“Conectou a BD Oracle");
231
UEM
A Parte de Inicialização DMI
// Criação de CallableStatement
sql_str = "{call IDADE(?, ?, ?)}";
cstmt = conn.prepareCall(sql_str);
// Configuração de parâmetro IN
cstmt.setInt(‘KAZUKI’, 25, out1);
232
116
A Parte de Execução e UEM
Fecho DMI
// Execução
cstmt.executeUpdate();
System.out.println(“Executou");
System.out.println(out1);
// Fecho
conn.close();
System.out.println(“Fechou conexão");
233
117