Você está na página 1de 117

DISCIPLINA:

BASE DE DADOS 1
O docente:
Hélder MC Muianga
 helder.muianga@uem.mz
 (+258) 82-4727160

Elaborado por: Hélder MC Muianga 1

Programação em
PL/SQL

1
UEM
Sumário do Curso DMI

O curso de base de dados ORACLE terá os


seguintes módulos:
 Introdução a bases de dados (20h)
 Linguagem SQL (Básico) (20h)
 Linguagem SQL (Avançado) (20h)
 Programação em PL/SQL (30h)
 Administração de base de dados Oracle (40h)
(Básico)
 Administração de base de dados Oracle(40h)
(Avançado)
3

UEM
Objectivos do curso DMI

Ao fim deste módulo o participante deverá estar habilatado em:


 Programar em PL/SQL usando:
 Estrutura de PL/SQL
 Variáveis em PL/SQL
 Estruturas de controle (IF…THEN… ELSE, FOR…LOOP)
 Cursor
 Processo de excepção
 Procedimento e Função
 Desenvolver sistemas usando PL/SQL
 PL/SQL + Linguagem de Programação
 Com Java, VB

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

Depois de terminar esta lição, deverá estar


capacitado para:
 Explicar a necessidade do PL/SQL

 Explicar os benefícios que advém do uso do


PL/SQL
 Identificar os diferentes tipos de blocos do PL/SQL

 Usar o iSQL*Plus como um ambiente de


desenvolvimento do PL/SQL
 Gerar mensagens de saída no PL/SQL

UEM
Questão 1 DMI

 Uma empresa do ramo industrial, tem feito


periodicamente um balanço dos seus rendimentos.
 Ao fazer cálculo de bónus de empregados, deve
seguir os seguintes critérios:
 Se esse empregado for do departamento de Vendas,
recebe 2000 e os restantes 1000.
 Caso esse empregado seja Gestor de Vendas recebe mais
1000.
 A questão é: Como resolver este problema
complicado usando SQL?

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;

A declaração SQL acima, é bastante simples e directa. Contudo, enfrentaremos


alguns problemas caso queiramos alterar os dados por si devolvidos segundo
uma certa condição. Deparamo-nos com algumas limitações do SQL.

Considere o seguinte problema, já modificado:


Para todo o empregado devolvido, verifique o seu deptno e o sal. Dependendo
do desempenho do departamento e do salário do empregado poderá querer
atribuir bónus diferentes a cada um dos empregados.

É fácil ver que se consiguirmos resolver o problema acima, poderemos de seguida


resolver também a Questão 1.

11

UEM
Porquê PL/SQL (Cont.) DMI

Olhando para o problema anterior, constatamos que precisamos


executar uma declaração SQL e ainda aplicar uma certa lógica
aos dados por si devolvidos. Usando SQL para resolver este
problema, precisaríamos de uma declaração SQL para cada
deptno e efectuar a referida bonificação a cada empregado sem
se esquecer que será preciso verificar o salário antes de atribuir
o bónus.
Desta forma o problema torna-se complicado. Sentimos que tudo
seria muito mais simples se tivéssemos declarações
condicionais (neste caso serviria para verificar o deptno e o sal).

PL/SQL foi concebido para responder a tal género de


necessidades, providenciando uma componente de
programação ao código SQL.
12

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

PL/SQL Mota de PL/SQL Executor de


ORACLE
Procedural Declaração
Mota de PL/SQL Executor de SQL Procedural
Procedural Declaração
SQL Procedural
ORACLE

Executor de SQL Executor de SQL

13
* Ferramentas : Oracle Forms, Oracle Report

UEM
Vantagens do PL/SQL DMI

1. Integração de construção procedural com SQL


• Quando executamos um comando SQL, este comunica
ao Servidor de BD o que deve ser feito e não como deve
ser feito. PL/SQL incorpora estas declarações de controle
e declarações condicionais junto com o SQL. Dá-nos um
melhor controle sobre as nossas declarações SQL e sua
execução. O problema visto antes, mostra a necessidade
de tal integração.
2. Melhoria no desempenho
• Sem o PL/SQL não seria possível combinar logicamente
várias declarações SQL que são enviadas para a BD
como sendo uma única unidade. Portanto PL/SQL envia
todas estas declarações, de uma só vez, sob forma de
um bloco. Isto reduz grandemente o número de
solicitações da BD.
14

7
Vantagens do PL/SQL UEM
(Cont.) DMI

1. Envio de declarações SQL 2. Envio um bloco


uma a uma à BD (inúmeras PL/SQL (apenas uma
solicitação da BD)
solicitações da BD)

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

Vantagens do PL/SQL UEM


(Cont.) DMI

3. Desenvolvimento de programas em módulos


 A unidade básica dum programa PL/SQL é um bloco. Estes blocos podem
ser sequenciais ou podem ser aninhados
 Manutenção e Depuração (melhora de legibilidade)
4. Integração com ferramentas da Oracle
 Apoia todos os tipos de dados e mais
 Formulários Oracle, Relatórios Oracle
5. Portabilidade
 Programa do PL/SQL pode ser executado em qualquer ambiente onde se
possa executar o Servidor Oracle independentemente da plataforma do
SO.
6. Controle de excepções
 PL/SQL garante controle eficiente de excepções. Podemos definir blocos
separados para lidar com excepções (veremos mais adiante como lidar
com excepções).

PL/SQL partilha mesmo tipo de dados que o SQL, com pequenas


excepções, e usa a mesma sintaxe para expressões.
16

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

 Um programa PL/SQL inclui um ou mais blocos que


podem estar separados ou aninhados. Existem três
tipos de blocos que compõem um programa PL/SQL:
Subprogramas
Anónimo Procedimento Função
[DECLARE] PROCEDURE nome FUNCTION nome
IS RETURN tipo_de_dado
BEGIN IS
--Declarações BEGIN BEGIN
--Declarações --Declarações
[EXCEPTION]
[EXCEPTION] [EXCEPTION]
END;
END; END;
19

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

Ferramentas Constructs Servidor Oracle Construct


Blocos Anónimos Blocos Anónimos
Procedimentos ou Funções Stored Procedures ou Stored Functions
Aplicações de Pack ages Stored Pack ages
Aplicações de Triggers Triggers da BD
Tipos de Objecto Tipos de Objecto

21

Ambientes de Programação UEM


PL/SQL DMI
 iSQL *Plus
 É a aplicação que funciona em browser (ex. Internet Explorer, Firefox, Opera e
mais)
 Conectar base de dados local e remota
 É possível executar todas as operações de programação
 Oracle JDeveloper 10g (grátis)
 É um software para desenvolver páginas web com GUI
 Estabelece conexão à BD com ajuda dum user-friendly wizard
 Pesquisa dados da BD à qual se está conectado
 Cria objectos e usuários de BD
 Cria, executa e depura programas de PL\SQL como procedimentos, funções e
packages
 PL/SQL Developer (versão trial)
 Uma aplicação para desenvolver programas PL\SQL
 É preciso atribuir privilégio DEBUG CONNECT SESSION ao usuário da BD
 Não usa comando SET

Oracle JDev e iSQL*Plus podem igualmente ser tidos como ambientes de


programação
22

11
UEM
Uso de iSQL*Plus DMI

 Inicializar o navegador (ex. IE, Firefox…)


 Escrever o seguinte URL:
 http://[endereço de servidor]:[Portos]/isqlplus
 Username : oracleXX
 Password : micti

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

 Clique no botão Execute

25

UEM
Saída Dum Bloco PL/SQL DMI

 Configure a visualização de saída no


iSQL*Plus usando o comando:
 SET SERVEROUTPUT ON
 Use o pacote pré-definido da Oracle e seus
procedimentos:
 DBMS_OUTPUT.PUT_LINE

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

 Torna a saída legível no SQL*Plus


 É dispensável o uso deste comando quando se usa
iSQL*Plus
Variável Valor Descrição
HEADING ON ou OFF Exibe títulos de coluna
LINESIZE Número Indica comprimento de uma linha
NULL Caracter Substitui valor de Nulo por outro
PAGESIZE Número Número de linhas por página
TIMING ON ou OFF Exibe a duração duma execução

Quando quiser saber valor da variável, use comando de SHOW


SHOW nome_de_variável_SET
29

UEM
PL/SQL Developer DMI

Acrescente
esta
declaração
30

15
UEM
Exemplos DMI

1. Qual dos seguintes blocos PL/SQL será executado com sucesso?


a) BEGIN
END;
b) DECLARE
quantidade INTEGER (10);
c) DECLARE
BEGIN
END;
d) DECLARE
quantidade INTEGER (10);
BEGIN
DBMS_OUTPUT.PUT_LINE(quantidade);
END;
2. Crie e execute um bloco anónimo que imprime na tela a seguinte
mensagem: “Meu primeiro bloco em PL/SQL”. Grave com o nome
plsql_exp01.sql

31

UEM
Objectivos DMI

Depois de terminar esta lição, deverá estar


capacitado para:
 Listar os identificadores válidos e inválidos

 Listar os usos das variáveis

 Declarar e inicializar variáveis

 Listar e descrever os diferentes tipos de dados

 Identificar e listar os benefícios do uso do


atributo %TYPE
 Declarar, usar e imprimir variáveis de ambiente

32

16
UEM
Sumário DMI

 Explicar a necessidade do PL/SQL


 Explicar os benefícios que advém do uso do
PL/SQL
 Identificar os diferentes tipos de blocos do
PL/SQL
 Usar o iSQL*Plus como um ambiente de
desenvolvimento do PL/SQL
 Gerar mensagens de saída no PL/SQL
33

UEM
Questão 2 DMI

 Na qualidade de operador da BD, solicita-se uma


listagem dos empregados dos departamentos 10 e
20.
 Adicionalmente questiona-se, se PL/SQL também
tem variáveis, uma vez tratar-se duma linguagem
procedural?

Como resolver esta questão?

d_no := 10; SELECT * Resultado1


FROM emp
d_no := 20; WHERE deptno=d_no; Resultado2
34

17
UEM
Uso de Variáveis DMI

 Variáveis são usadas para:


 Armazenamento temporário de dados
 SELECT coluna [, coluna …] INTO var1 [, var2 …] FROM …
 Manipulação de valores armazenados
 Podemos usar o valor armazenado para manipular/processar dados
 Reusabilidade
 Depois de declaradas, as variáveis podem ser usadas repetidamente
por várias aplicações bastando para tal fazer referência às mesmas.

SELECT
ename,
Alberto emp_nome
deptno
INTO
emp_nome,
emp_deptno
FROM… 10 emp_deptn
35
o

UEM
Identificadores DMI

Os identificadores são usados para:


• Nomear uma variável
• Providenciar a convenção para os nomes das
variáveis como sendo:
• Deve começar sempre com uma letra
• Pode incluir letras e números
• Pode incluir caracteres especiais tais como: símbolo do
dólar ($), underscore (_), símbolo de libra (#)
• Deve ter tamanho máximo de 30 caracteres
• Não deve ser uma palavra reservada

36

18
UEM
Identificadores VS Variáveis DMI

Qual é a diferença entre Identificadores e


variáveis?
• Identificadores são nomes das variáveis.
• Variáveis são locais de armazenamento temporário
de dados. O armazenamento permanente dos
dados é feito na memória. Portanto, as variáveis
apontam para este ponto da memória a partir do
qual os dados podem ser lidos e modificados.
• Identificadores são usados para nomear qualquer
objecto PL/SQL como: variáveis, tipos, cursores e
subprogramas.
• Variáveis são usadas para armazenar qualquer
objecto PL/SQL como: variáveis, tipos, cursores e
subprogramas. 37

Controle de Variáveis em UEM


PL/SQL 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

Declaração e Inicialização UEM


de Variáveis PL/SQL (cont.) DMI

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

Delimitadores Com UEM


Apóstrofes DMI

Muitas palavras Inglesas levam consigo apóstrofes e por vezes


pode haver necessidade de gerar saídas para esse tipo de
palavras:

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

 Sigue a convenção para atribuição de nomes


 Dê nomes significativos
 Inicialize sempre as variáveis designadas como sendo NOT NULL e
CONSTANT
 Evite atribuir nome duma coluna a um identificador
DECLARE
enome VARCHAR2(20);
BEGIN
SELECT enome
INTO enome
FROM emp
WHERE empno=50;
END;
/

45

Directrizes Para Declaração e


UEM
Inicialização de Variáveis DMI
PL/SQL(Cont.)
• Declare um identificador por linha para legibilidade e fácil
manutenção de código
DECLARE
nome VARCHAR2(20);
num_dept NUMBER(2);
salario NUMBER(6);
BEGIN....
• Inicialize as variáveis com o operador de atribuição (:=) ou com a
palavra DEFAULT

nome VARCHAR2(20) := ‘EDSON’;

nome VARCHAR2(20) DEFAULT ‘EDSON’;

46

23
UEM
Questão 4 DMI

Quantos tipos de variáveis existem em


PL/SQL?

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

Declaração de Variáveis UEM


Escalares DMI

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

 Ao declarar uma certa variável, será preciso


pesquisar o tipo de dado da coluna afectada?
 Por exemplo, declaramos a variável emp_num,
teremos de pesquisar o tipo de dado da coluna empno
na tabela emp?

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

Declaração de Variáveis UEM


BOOLEAN DMI

 Só podem receber valores TRUE, FALSE e


NULL
 Expressões condicionais usam operadores
lógicos AND, OR e operador unário NOT
para verificar os valores da variável
 Sempre cedem TRUE, FALSE ou NULL
 Operações aritméticas, caracteres e
expressões de data podem ser usadas para
devolver um valor booleano
54

27
UEM
Variáveis de Ambiente DMI

Variáveis de ambiente são:


 Criadas no ambiente de desenvolvimento

 Também designadas de variáveis anfitriãs

 Criadas usando a palavra reservada VARIABLE

 Usadas em declarações SQL e nos blocos PL/SQL

 Acedidas mesmo depois de se ter executado o


bloco PL/SQL
 Referenciadas com uma precedência de dois
pontos (:)

55

Variáveis de Ambiente UEM


(Cont.) DMI

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

Imprimindo Variáveis de UEM


Ambiente(Cont.) DMI

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

 São usadas para receber os dados de entrada do usuário no momento


de execução
 São referenciadas num bloco PL/SQL precedido do símbolo &
 São usadas para evitar uma codificação explícita de valores que
podem ser obtidos no momento da execução

VARIABLE emp_salario NUMBER


SET AUTOPRINT ON
DECLARE
emp_numero NUMBER(6) := &emp_numero ;
BEGIN
SELECT sal INTO :emp_salario
FROM emp
WHERE empno=emp_numero;
END;
/
59

Variáveis de Substituição UEM


(Cont.) 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

Uso do DEFINE Para UEM


Variáveis do Usuário DMI

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

 Analisemos a seguinte questão:


 Ao referenciar dados da tabela, temos que declarar
variáveis para cada coluna? (É muito trabalhoso…)
 Ao existir muitas variáveis a legibilidade é inexistente
 Não há maneira de declarar várias variáveis duma só vez?

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

Campo1 (DATA) Campo2 (VARCHAR2) Campo3(NUMBER) Campo4(BLOB)

19-JUN-2006 MAPUTO 1980

64

32
UEM
Questão 7 DMI

 Existem alguns comandos escritos com letra


maiúscula e outras minúscula. Existe alguma
diferença? Ou existe alguma norma?
 Em declaração SQL tem muitos símbolos. Por
exemplo, =, <, >, =<, =>, &, %, (, ) e mais. Agora,
quantos símbolos tem em SQL?

65

UEM
Letra Maiúscula e Minúscula DMI

 Não tem diferença entre letra maiúscula e


minúscula, excepto para dados
 Exemplos
 DECLARE e declare Não há
diferença
 SET SERVER ON e Set Server On

 ‘JOHN’ e ‘John’ e ‘john’ Há


diferença

66

33
UEM
Objectivos DMI

Depois de terminar esta lição, deverá estar


capacitado para:
 Identificar unidades léxicas num bloco PL/SQL
 Usar funções SQL pré-definidas no PL/SQL
 Descrever quando é que ocorre um conversão
explícita e implícita e quando devem ser assim
tratadas
 Construir blocos aninhados e qualificar os nomes
das variáveis
 Escrever códigos legíveis com uma indexação
apropriada

67

Unidades léxicas em um UEM


Bloco de PL / SQL DMI

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

 São símbolos que têm um significado especial:

“ ; ”, “ + ”, “ := ”

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

 Caracter literal : ‘John’, ‘123’, ’12-JAN-1999’

 Numérico literal : 438, 12544.77

 Boolean literal : TRUE, FALSE e NULL

 Comentários
 -- Para comentar numa linha
 /* */ Para comentar em múltiplas linhas

69

UEM
Identificadores DMI

 São nomes usados para referenciar objectos em


PL/SQL
 Existem restricções
 Palavras reservadas não podem ser usadas como
identificadores
 Declare, begin, end, exception e mais…
 Palavra com espaço é inválida como Identificador
 Se quisermos usar palavras reservadas ou
palavras com espaço, devemos colacar ente “ ”:
1. “begin date” DATE;
2. “end date” DATE;
3. “exception thrown” BOOLEAN DEFAULT TRUE;

70

35
UEM
Delimitadores DMI

 São símbolos que têm um significado especial

Símbolos simples Símbolos combinados


símbolo significado símbolo significado
+ Operador de adição <> Operador de desigualdade
- Operador de subtração != Operador de desigualdade
* Operador de multiplicação || Operador de concatenação
/ Operador de divisão -- Indicador de comentário de linha única
= Operador de igualdade /* Delimitador de início de comentário
@ indicador de acesso remoto */ Delimitador de fim de comentário
; delimitador de declaração := Operador de tarefa

71

UEM
Literais DMI

 Caracteres e data devem estar entre ‘ ‘:


 Nome_de_empregado := ‘Henderson’;
 Números podem ser valores simples ou sob
notação científica
 2E5, significa 2*105 = 200000
 Declarações podem ser feitas em várias
linhas

72

36
Comentários Dentro do UEM
Código DMI

 Os comentários não são executados pelo Servidor Oracle


 Há dois tipod de comentários
 Para uma linha
 -- uma linha
 Para várias linhas
 /* início
...
fim */
 Exemplo
DECLARE

sal NUMBER(9,2);
BEGIN -- secção que começa à execução
/* Armazena o salário anual baseado
no valor mensal auferido por cada empregado*/
sal := sal_mes * 12;
END;
/ 73

UEM
Questão 8 DMI

 Com os conhecimentos que se tem sobre


SQL, no caso de PL/SQL, podemos
aproveitar conhecimento de SQL?

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;
/

4. Crie um bloco anónimo em que:


a) Imprima a data de hoje e a data de amanha, acompanhadas
das seguintes mensagens: Hoje é dia: <dia> e amanha será
dia: <dia>
b) Imprime na tela o nome completo, o salário e a data de
contratação de qualquer empregado que for solicitado.
c) Declara as seguintes variáveis: nome (com o mesmo tipo de
dado que a coluna ename da tabela emp) e salario ( do mesmo
tipo que a coluna sal da tabela emp).
76

38
UEM
Funções SQL no PL/SQL DMI

 Disponíveis nas declarações procedural


1. Linha que devolve um número
2. Linha que devolve um caracter
3. Conversão de tipo de Dados
4. Data
5. Timestamp
6. GREATEST e LEAST
7. Funções Misturadas
 Não disponível nas declarações procedural
1. DECODE
2. Funções agregadas (Funções estatísticas)

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

Converte o nome do empregado para letra


minúscula
nome_de_emp := LOWER(nome_de_emp);

78

39
Conversão de Tipo de UEM
Dados DMI

 Converte dados a tipos de dados comparáveis


 São de dois tipos:
1. Conversões implícitas
2. Conversões explícitas
 Algumas funções de conversão
 TO_CHAR
 TO_DATE
 TO_NUMBER
 TO_TIMESTAMP

79

Conversão de Tipo de UEM


Dados (cont.) DMI

 Conversão implícita
data_de_trabalho DATE := ’01-MAY-2000’ ;

 Erro de conversão implícita


data_de_trabalho DATE := ’February 02, 2000’ ;

 Conversão explícita
data_de_trabalho DATE :=
TO_DATE(’February 02, 2000’, ‘Month DD, YYYY’) ;

80

40
UEM
Blocos Aninhados DMI

 Blocos PL/SQL podem DECLARE


ser aninhados …
 A secção executável BEGIN
(BEGIN … END;) pode …
conter os Blocos
DECLARE
Aninhados

 A secção de excepção BEGIN
pode conter Blocos …
Aninhados END;
EXCEPTION

END;

81

Alcance e Visibilidade da UEM


Variável Num Bloco DMI

SET SERVEROUTPUT ON;


DECLARE
nome_de_pai VARCHAR(20) := 'Patrick';
data_de_ani DATE := '20-Apr-1972';
BEGIN
DECLARE
nome_de_filho VARCHAR(20) := 'Mike';
data_de_ani DATE := '11-DEC-2003';
BEGIN
DBMS_OUTPUT.PUT_LINE('Nome do Pai é ' || nome_de_pai);
DBMS_OUTPUT.PUT_LINE('Nome do filho é ' || nome_de_filho);
DBMS_OUTPUT.PUT_LINE('A data do aniversário é ' || data_de_ani);
END;
DBMS_OUTPUT.PUT_LINE('A data do aniversário é ' || data_de_ani);
END;

82

41
Alcance e Visibilidade da UEM
Variável Num Bloco(cont.) DMI

 O resultado

Nome do Pai é Patrick


Nome do filho é Mike
A data do aniversário é 11-DEC-03
A data do aniversário é 20-APR-72
PL/SQL procedure successfully completed.

 Alcance é o bloco do programa onde a variável é declarada e


acessível.
 A visibilidade é o bloco do programa onde a variável pode ser acedida
sem precisar de usar um qualificador
 As variáveis afectam as variáveis que são dentro dos seus blocos
 Se se tiver mesmo nome para duas variável distintas em blocos
aninhados (exterior e interior), a variável interior tem prioridade.

83

UEM
Qualificar Um Identificador DMI

 Esta qualificação é feita quando se pretende usar a variável


exterior no bloco interior mesmo que este último tenha também
declarado uma variável com o mesmo nome. Neste caso
podemos nomear bloco como sendo <<nome de bloco>>

SET SERVEROUTPUT ON;


<<exterior>>
DECLARE
data_de_ani DATE := '20-Apr-1972';
BEGIN
DECLARE
data_de_ani DATE := '11-DEC-2003';
BEGIN
DBMS_OUTPUT.PUT_LINE('A data do aniversário é ' || exterior.data_de_ani);
END;
END;
84

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 Exponencial (**)

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

Operadores no PL/SQL UEM


(cont.) DMI

 Exemplos
 Incrementa o contador de loop
contador := contador + 1;

 Atribui um valor Booleano


bom_sal := sal BETWEEN 50000 AND 150000;

 Valida se o número de empregado não é nulo


valido := (empno IS NOT NULL);

86

43
Notificação de Operador no UEM
PL/SQL DMI

 Quando se trabalha com valores nulos, podem-se


evitar alguns erros comuns, recordando as
seguintes regras:
 Comparações envolvendo nulos sempre retornam
NULL.
 Aplicando o operador lógico NOT ao nulo retorna
NULL.
 Em declarações de controle condicional, se a
condição produz NULL, a sequência de declarações
associadas à condição não é executada.

87

UEM
Formas de Programação DMI

 Crie código que facilita a manutenção :


 Documentando o código com comentários
 Desenvolvendo convenções para o código
 Desenvolvendo convenções para a nomenclatura de
identificadores e outros objectos
 Criando alinhamento de código

Categoria Caso convenção Exemplos


SQL maiúscula SELECT, INSERT
PL/SQL maiúscula DECLARE, BEGIN, IF
Tipos de Dados maiúscula VARCHAR2, BOOLEAN
Identificadores e parâmetros minúscula v_sal, emp_cursor, g_sal, p_emp
tabela e coluna de base de dados minúscula empno, dname, sal, job

88

44
Alinhamento (Indentation) UEM
de Código DMI

 É melhor fazer alinhamento dó código para a


sua própria legibilidade
 Exemplo
BEGIN
IF x=0 THEN
y=1;
END IF;
END;
/

89

UEM
Sumário DMI

 SQL funções em PL/SQL


 Blocos Aninhados
 Conversões explícitas
 Variáveis em blocos aninhados

90

45
Declarações de SQL no UEM
PL/SQL DMI

 Retornar linhas da base de dados pelo uso


do comando SELECT
 Alterar o conteúdo das linhas da base de
dados, usando comandos DML
 Controlar a transacção com os comandos
COMMIT, ROLLBACK ou SAVEPOINT

91

Declarações de SELECT no UEM


PL/SQL DMI

 Cláusula INTO é consultado??????


 Consultas devem retornar somente uma linha
 Exemplo
SET SERVEROUTPUT ON
DECLARE
nome_de_emp VARCHAR2(25);
BEGIN
SELECT ename INTO nome_de_emp
FROM emp WHERE empno=7369;
DBMS_OUTPUT.PUT_LINE(‘Nome de empregado é ’ || nome_de_emp);
END;
/

92

46
Retorno de dados no UEM
PL/SQL DMI

 Retorne a hiredate e a sal do empregado


especificado
 Consultas devem retornar somente uma linha
 Exemplo
DECLARE
emp_hiredate emp.hiredate%TYPE;
emp_sal emp.sal%TYPE;
BEGIN
SELECT hiredate, sal
INTO emp_hiredate, emp_sal
FROM emp
WHERE empno=7369;
END;
93
/

Retorno de dados no UEM


PL/SQL (cont.) DMI

 Retorne o total dos salários de todos os


empregados do departamento especificado
 Exemplo
SET SERVEROUTPUT ON
DECLARE
sum_sal NUMBER(10, 2);
no_dept NUMBER NOT NULL := 10;
BEGIN
SELECT SUM(sal) -- função agregada
INTO sum_sal
FROM emp
WHERE deptno=no_dept;
DBMS_OUTPUT.PUT_LINE(‘O total dos salários é ’ || sum_sal);
END; 94
/

47
Manipulação de Dados UEM
Usando PL/SQL DMI

 Altere o conteúdo das tabelas da base de dados


usando comandos DML:
 INSERT …para inserir
 UPDATE…para actualizar
 DELETE …para remover
 MERGE …para sincronizar (misturar ou fundir)

95

UEM
Inserção de Dados DMI

 Adicionar uma nova instância de empregado


na tabela emp
 Exemplo
BEGIN
INSERT INTO emp
( empno, ename, job
, hiredate, sal, comm
, deptno
) VALUES
( emp_seq.NEXTVAL, ‘Ruth’, ‘SALESMAN’
, SYSDATE, 7000, 1400
, 40
);
END; 96
/

48
UEM
Actualização de Dados DMI

 Aumentar o salário de todos os empregados


que tenham a categoria CLERK
 Exemplo
DECLARE
sal_aumento emp.sal%TYPE := 800;
BEGIN
UPDATE emp
SET sal = sal + sal_aumento
WHERE job = ‘CLERK’;
END;
/

97

UEM
Eliminação de Dados DMI

 Eliminar as linhas que pertencem ao


departamento 10 da tabela emp.
 Exemplo
DECLARE
d_no emp.deptno := 10;
BEGIN
DELETE FROM emp
WHERE deptno = d_no;
END;
/

98

49
UEM
Fusão de Linhas DMI

 Inserir ou actualizar linhas na tabela emp_copiada


 Ao inserir uma nova linha, se já existir uma linha que tem
mesmo valor de PK, actualize-a em vez de inserí-la.

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

 O seu chefe disse que


 O seu programa retorna apenas uma linha, não
é?
 Não se pode efectuar uma consulta que retorna
várias linhas da tabela?

Variável
100

50
Como é que se retornam várias UEM
linhas no Bloco do PL/SQL DMI

 Já foi aprendido como fazer uma consulta de


SQL que retorna uma única linha no Bloco do
PL/SQL
 Deve-se usar SELECT … INTO … FROM …
 Ao retornar várias linhas da tabela, usa-se o
CURSOR

101

UEM
Cursor de SQL DMI

 CURSOR é uma referência à área de memória


privada alocada pelo Servidor Oracle
Servidor Oracle

SELECT (seleccionar)

Conjunto Executado OPEN (abrir)

FETCH (trazer)
102

51
UEM
Cursor de SQL DMI

 CURSOR é indicador do conjunto


executado das linhas retornadas
 Estas linhas são executadas
respectivamente pelo Servidor de Oracle
 Há dois tipos de cursores
 Cursores implícitos
 São criados e manejados interiormente pelo servidor
de Oracle para processar a declaração de SQL
 Cursores explícitos
 São explicitamente declarados pelo programador 103

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

 Use os atributos do Cursor SQL, para poder


testar o resultado da sua declaração de SQL

SQL% FOUND Atributo Booleano que retorna


VE RDADE IRO se a m ais recente
declaração de SQL devolver pelo m enos
um a linha.
SQL% NOTFOUND Atributo Booleano que retorna
VE RDADE IRO se a m ais recente
declaração de SQL não devolver
nenhum a linha.
SQL% ROW COUNT Um valor núm erico inteiro que indica o
núm ero de linhas afectadas pela m ais
recente declaração de SQL 105

Atributos de Cursor SQL para UEM


cursores implícitos (cont. 1) DMI

 Remover as linhas que contém o número de


empregado especificado, da tabela emp. Exibir a
seguir o número de linhas removidas
 Exemplo

VARIABLE linhas_removidas VARCHAR2(30)


DECLARE
e_no emp.empno%TYPE := 7635;
BEGIN
DELETE FROM emp
WHERE empno=e_no;
:linhas_removidas := (SQL%ROWCOUNT || ' linhas foram removidas.');
END;
/
PRINT linhas_removidas 106

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

 Emissão de Declarações DML, declarações


de controle de transacção e declarações de
DDL em PL/SQL
 Clausula de INTO que é obrigatório para
SELECT em PL/SQL
 CURSOR implícito e explícito
 Atributos de CURSOR implícito
 SQL%FOUND, SQL%NOTFOUND e
SQL%ROWCOUNT

108

54
UEM
Questão DMI

 O seu colega, o Edson disse:


 Eu ouvi dizer que PL/SQL tem estruturas de
controle. É verdade?
 Agora, eu tenho de usar a ordem de divergência
no PL/SQL, como também tenho de repetir
processos.
 É possível?

109

Controle de Fluxo de UEM


Execução DMI

 Pode-se mudar o fluxo lógico das


declarações dentro do bloco do PL/SQL,
usando estruturas de controle
 Declaração IF
 Expressão CASE
 Estrutura de controle de LOOP

110

55
Diagrama de IF, CASE e UEM
LOOP DMI

 IF deve diferenciar o processo mediante uma condição


 CASE separa os casos mediante os valores da condição
 LOOP repete processo enquanto a condição for verdadeira

IF CASE LOOP

Falso Falso
Condição Condição Condição
Valor 1 Valor 2 Valor 3
Verdadeiro Verdadeiro

Processo 1 Processo 3

Processo 2 Processo 1 Processo 1


Processo 2

111

UEM
Declaração IF DMI

 IF é semelhante à estrutura de IF de qualquer


linguagem procedural
 Sintaxe
IF condição THEN
Declarações;
[ ELSIF condição THEN
Declarações;]
[ ELSE
Declarações;]
END IF;

1. Se resultado da condição for verdadeiro, são executadas as declarações


correspondentes .
2. Se não for verdadeiro, a próxima condição depois de ELSIF é avaliada.
3. Se todas as condições explícitas não forem verdadeiras, as declarações existentes
112
no ELSE são executadas.

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

Declarações de IF THEN UEM


ELSE DMI

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;
/

a) Se minha_idade não for menor do que 11, é


executado declarações do ELSE
114

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.

Valores de NULL na UEM


Declarações IF DMI

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;
/

a) A variável minha_idade é declarada mas não é inicializada


b) A condição IF retorna o valor NULL
c) Em tal caso, o controle vai para o ELSE
116

58
UEM
Expressões de CASE DMI

 Expressão de CASE selecciona o resultado duma


expressão satisfeita
 Para seleccionar o resultado, a declaração CASE
usa expressões. O valor retornado por estas
expressões é usado para seleccionar uma de várias
alternativas
 Sintaxe
CASE [selector]
WHEN expressão1 THEN resultado1
WHEN expressão2 THEN resultado2

WHEN expressãoN THEN resultadoN
[ELSE resultadoN+1]
END;
/ 117

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

Controlando Nulos UEM


DMI
 Ao trabalhar com valores nulos, evite alguns erros
comuns, usando as seguintes normas:
 Comparações simples envolvendo nulos sempre retornam
NULL
 A aplicação do operador lógico de NOT à um nulo, retorna
NULL
 Em declarações de estruturas controle, se a condição
retornar NULL, as declarações associadas à condição não
são executadas
X := 5; X := NULL;
Y := NULL; Retorna NULL Y := NULL; Rende NULL
… Não é TRUE … Não é TRUE
IF x <> y THEN IF x = y THEN
-- Declarações não são executadas -- Declarações não são executadas
END IF; END IF; 120

60
UEM
Tabelas de lógica DMI

AND Resultado OR Resultado


TRUE TRUE TRUE TRUE TRUE TRUE
TRUE FALSE FALSE TRUE FALSE TRUE
FALSE TRUE FALSE FALSE TRUE TRUE
FALSE FALSE FALSE FALSE FALSE FALSE
TRUE NULL NULL TRUE NULL TRUE
NULL TRUE NULL NULL TRUE TRUE
FALSE NULL FALSE FALSE NULL NULL
NULL FALSE FALSE NULL FALSE NULL
NULL NULL NULL NULL NULL NULL

NOT Resultado
TRUE FALSE
FALSE TRUE
121
NULL NULL

UEM
Condições Booleanas DMI

 Qual é o valor de bandeira em cada caso?


bandeira := dinheiro_bandeira AND banco_bandeira;

dinheiro_bandeira banco_bandeira bandeira


TRUE TRUE
TRUE FALSE
NULL TRUE
NULL FALSE

122

61
Controle de Repetição: UEM
Declarações de LOOP DMI

 PL/SQL disponibiliza várias versões de estruturas


LOOP, para repetir declaração ou sequência de
declarações
 LOOP básico
 Executa acções repetitivas sem condições globais
 WHILE LOOP
 Executa as acções repetitivas baseado numa condição
 FOR LOOP
 Executa acções repetitivas baseado num intervalo definido

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

 Use WHILE LOOP para repetir declarações


enquanto a condição inicial for verdadeira
 Sintaxe
WHILE condição LOOP
Declaração1;

END LOOP;

 Exemplo
WHILE idade < 10 LOOP
idade := idade + 1;
END LOOP;
125

UEM
FOR LOOP DMI

 Use FOR LOOP para repetir declarações que tem


contador definido num intervalo
 Sintaxe
FOR contador IN [REVERSE] limite inferior .. limite superior LOOP
Declaração1;
Declaração2;

END LOOP;

 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

 Condicional (declaração de IF)


 Expressões de CASE e declarações de
CASE
 LOOP
 Declarações de EXIT

128

64
UEM
Questão DMI

 O Edson veio perguntar


 Eu quero usar variáveis que armazenam vários
tipos de dados.
 É possível?

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

 É uma estrutura de unidade de dados


 Deve conter pelo menos um componente de alguma
escalar chamado campo
 Sintaxe
TYPE nome_de_tipo IS RECORD
(declaração_de_campo [, declaração_de_campo] …);

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

Criando Registros do UEM


PL/SQL DMI

 Declara variáveis para armazenar ename, job


e sal da tabela emp
 Exemplo

TYPE tipo_registro_emp IS RECORD -- Novo tipo de dados
(ename VARCHAR2(10),
job VARCHAR2(9),
sal NUMBER(7,2));
reg_emp tipo_registro_emp; -- A variável é reg_emp

132

66
Estrutura de Registros de UEM
PL/SQL DMI

Campo1(tipo) Campo2(tipo) Campo3(tipo)

 Exemplo
empno ename job
NUMBER(4) VARCHAR2(10)VARCHAR2(9)

 Campos no registro são acessados com o


nome do registro. Para referir ou inicializar
cada campo, use o ponto
133
nome_registro := empno

UEM
Questão DMI

 Você pensou assim:


 Não há maneira de as variáveis compostas
armazenarem dados da linha duma tabela.

134

67
UEM
Atributo %ROWTYPE DMI

 Sintaxe
DECLARE
identificador referência%ROWTYPE;

 Vantagens de uso de %ROWTYPE


 Usando registro, o número de colunas e seu tipo de dados
na base de dados, não precisa ser sabido
 O número de colunas e o seu tipo de dados na base de
dados usando registro, podem alterar sem afectar o seu
uso
 O atributo é muito útil quando a declaração SELECT
retorna uma linha inteira duma tabela

135

Exemplo: UEM
Atributo %ROWTYPE DMI

DEFINE emp_id = 7999;


DECLARE
reg_emp emp%ROWTYPE;
BEGIN
SELECT * INTO reg_emp FROM emp
WHERE empno=&emp_id;
/* Insere a nova linha para tabela de emp_aposentado */
INSERT INTO emp_aposentado(empno, ename, job, mgr,
hiredate, leavedate, sal, comm, deptno)
VALUES(reg_emp.empno, reg_emp.ename, reg_emp.job,
reg_emp.mgr, reg_emp.hiredate, SYSDATE, reg_emp.sal,
reg_emp.comm, reg_emp.deptno);
END;
/
136

68
Inserção de Registros que UEM
Usam %ROWTYPE DMI

DEFINE emp_id = 7999;


DECLARE
reg_emp emp_aposentado%ROWTYPE;
BEGIN
SELECT * INTO reg_emp FROM emp;
WHERE empno=&emp_id;
/* Insere a nova linha para tabela de emp_aposentado */
INSERT INTO emp_aposentado(empno, ename, job, mgr,
hiredate, leavedate, sal, comm, deptno)
VALUES(reg_emp.empno, reg_emp.ename, reg_emp.job,
reg_emp.mgr, reg_emp.hiredate, SYSDATE, reg_emp.sal,
reg_emp.comm, reg_emp.deptno);
END;
/
137

Actualização duma Linha na UEM


Tabela Usando Registro 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;

 A palavra chave ROW é usada para representar a linha inteira138

69
UEM
Questão DMI

 O seu colega veio perguntar:


 No caso de registos, nós podemos retornar os
todos os dados de uma linha inteira
 Agora, é possível retornar todos os dados duma
coluna?
Registo
TOM 200 MAPUTO

coluna1 coluna2 coluna3


TOM 200 MAPUTO
SMITH 300 MATOLA
MAPUTO
JOHN 250 ZIMPETO
MATOLA
ZIMPETO 139

Tabelas de INDEX BY ou UEM


Ordens associativas DMI

 Ordens associativas são estruturas do PL/SQL com


duas colunas:
 Inteiro ou caracter de tipo de chave primária
 Coluna do tipo escalar ou do tipo de dados de registro
 Não são compelido no tamanho. Porém o tamanho
depende de valores da chave de tipo de dados
 Se coluna for do tipo escalar pode possuir somente um
valor
 Se a coluna for tipo de registro, pode possuir vários
valores

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;

 Exemplo : Declarar o INDEX BY tabela para


armazenar o nome de empregado

TYPE tipo_tabela_ename IS TABLE OF
emp.ename%TYPE
INDEX BY PLS_INTEGER;

ttp tipo_tabela_ename; 141

Estrutura de Tabela de UEM


INDEX BY DMI

Unique Key Valor


… …
1 Jones
5 Smith
3 Maduro
… …

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

Uso de Métodos de Tabela UEM


de INDEX BY DMI

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

 Define um variável de tabela de INDEX BY


para guardar uma linha inteira de tabela
DECLARE
TYPE tipo_tabela_dept IS TABLE OF dept%ROWTYPE
INDEX BY PLS_INTEGER;
tabela_dept tipo_tabela_dept;

145

Registros de Tabela de UEM


INDEX BY (cont.) DMI

Tabela emp
empno ename job mgr sal deptno

TYPE tipo_tabela_emp IS TABLE OF


emp%ROWTYPE
INDEX BY PLS_INTEGER;

PLS_INTEGER Estrutura de tabela emp 146

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

Tabela Composta UEM


(Aninhada) DMI

 Tabela composta tem semelhante de INDEX


BY Funcionalmente
 Chave é a partir de 1, chave não é possível valor
negativo

148

74
VARRAY: Variable-size UEM
arrays DMI

 VARRAY é semelhante a tabelas de PL/SQL, sendo


que o VARRAY é constrangido pelo tamanho.
 VARRAY é válido ao nível do schema

 Exemplo:
TYPE tipo_varray_loc IS VARRAY(3) OF dept.loc%TYPE;
escritorios tipo_varray_loc;

O tamanho deste VARRAY é restrito a 3


Se tentar inicializar o VARRAY com mais do que três elementos,
uma mensagem de erro “Subscript outside of limit” é exibida

149

UEM
Sumário DMI

 O formando deverá ter aprendido:


 A definir e a referenciar variáveis de PL/SQL com
o tipo de dados composto:
 Registos PL/SQL
 Tabelas INDEX BY
 Registos de tabela INDEX BY
 A definir um registro PL/SQL pelo uso do atributo
%ROWTYPE

150

75
UEM
Questão DMI

 O Edson disse que


 Eu quer ter resultado de consulta dentro do variável.
 Por exemplo, agora existe a consulta “SELECT * FROM
emp WHERE deptno=10”. Eu quero saber nos variáveis
que armazena resultado desta consulta.
 Não há?
 Você vai responder tem, este variável chama-se
CURSOR

151

UEM
Cursores: O que são? DMI

 Toda a declaração SQL executada pelo Servidor


Oracle possui um cursor individual associado:
 Existem dois tipos de cursores:
 Cursores Implícitos: (já aprendidos)
 Declarados e manejados internamente pelo servidor
Oracle para processar todas DML e declarações
SELECT do PL/SQL
 Cursores Explícitos:
 Explicitamente declarados pelo programador

152

76
UEM
Cursores Explícitos DMI

 Pode usar cursores explícitos em PL/SQL quando


tiver uma declaração SELECT que retorna múltiplas
linhas.
 Com o cursor poderá processar cada linha retornada
pela declaração de SELECT.

153

Controlo de Cursores UEM


Explícitos DMI

 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

DECLARAR ABRIR BUSCAR VAZIO? Sim FECHAR


154

77
Controlo de Cursores UEM
Explícitos (cont.) DMI

1. Abrir (OPEN) o Cursor


linha1 Indicador de
linha2 Cursor
linha3
linha4
2. Buscar (FETCH) a Linha

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;

Se a consulta não retornar qualquer linha quando a cursor estiver aberto, o


PL/SQL não levantará qualquer excepção. 157
Porém, poderá usar <nome_cursor>%ROWCOUNT para confirmar o estado do
cursor

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;

1. O Cursor FOR Loop facilita o processamento de


cursores explícitos.
2. Não precisa de declarar o OPEN, FETCH, EXIT e
CLOSE explicitamente.
3. O registo é implicitamente declarado. Declare somente
o cursor. 161

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

 Busca linhas somente quando o cursor estiver


aberto
 Use o atributo %ISOPEN antes de executar uma
busca para testar se o cursor está aberto
Exemplo
IF NOT cursor_emp%ISOPEN THEN -- Se não estiver aberto
OPEN cursor_emp;
END IF;
LOOP
FETCH cursor_emp…

163

Exemplo de %ROWCOUNT UEM


e %NOTFOUND DMI

 %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

 Não precisa de declarar o cursor

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

 Nega o acesso a outras sessões durante a


sua transacção trancando explicitamente
 Tranca as linhas antes do UPDATE ou
DELETE

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

A Cláusula WHERE UEM


CURRENT OF DMI

 Sintaxe
WHERE CURRENT OF cursor ;

 Estes cursores usam-se para actualizar ou


remover a linha corrente
 A cláusula WHERE CURRENT OF é usada
juntamente com a cláusula FOR UPDATE na
consulta para trancar as linhas primeiro.
 Usa-se a cláusula WHERE CURRENT OF
para referenciar a linha corrente a partir dum
cursor explícito
170

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

 O formando deverá ter aprendido:


 A distinguir cursores:
 Implícitos: usados para todas as declarações DML e consultas que
retornem uma única linha;
 Explícitos: usados para consultas que retornem zero, uma ou mais
linhas.
 A criar e tratar cursores explícitos
 A usar loops simples e cursores FOR loops para tratar linhas
múltiplas num cursor
 A avaliar o estado cursor usando os atributos dum cursor
 A usar as cláusulas FOR UPDATE e WHERE CURRENT OF
para actualizar ou remover a linha correntemente buscada.

172

86
UEM
Questão DMI

 Os meus programas as vezes causam erros


 Quando ocorrem erros os programas param no
meio da execução
 Caso ocorram erros eu quero executar outro
processo para resolver ou evitar problemas

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;
/

A sua declaração retornada várias linhas. Considere uso de CURSOR.176


PL/SQL procedure successfully completed.

88
Tratamento de Excepções UEM
em PL/SQL DMI

 Uma excepção é um erro em PL/SQL que é


levantado durante a execução dum programa.
 Uma excepção pode ser levantada:
 Implicitamente: pelo Servidor Oracle
 Explicitamente: pelo programa
 Uma excepção pode ser tratada:
 Usando um meio de a segurar
 Propagando-a para um ambiente de chamamento

177

UEM
Tipos de Excepção DMI

 Predefinido pelo Servidor Oracle


 Um dos 20 erros mais comuns
Exemplo: TOO_MANY_ROWS (ORA-01422)
Disparada  Não Predefinido pelo Servidor Oracle
implicitamente
 Qualquer outro erro padrão do Servidor
Oracle
 ORA-?????

 Definido pelo usuário


Disparada
explicitamente
 O programador determina a condição de erro
 Deve ser declarada dentro do secção
declarativa
178

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

Directrizes para Segurar UEM


Excepções DMI

 A palavra-chave EXCEPTION começa a


secção de tratamento da excepção
 É permitido o uso de vários tratadores de
excepção
 Somente um tratador é processado antes de
se sair do bloco
 A cláusula WHEN OTHERS é a última a ser
declarada.

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

 Seguremos o erro do servidor Oracle número -01400,


não pode inserir NULL.
SET SERVEROUTPUT ON
DECLARE
PK_excep EXCEPTION;
PRAGMA EXCEPTION_INIT (PK_excep, -01400);
BEGIN
INSERT INTO dept (deptno, dname) VALUES(80, NULL);
EXCEPTION
WHEN PK_excep THEN
DBMS_OUTPUT.PUT_LINE('Operação de Inserção Falhada!');
DBMS_OUTPUT.PUT_LINE(SQLCODE);
DBMS_OUTPUT.PUT_LINE('ORA' || TO_CHAR(SQLCODE, '00000'));
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
182
/

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

 O formando deverá ter aprendido:


 A definir excepções em PL/SQL
 A adicionar uma secção EXCEPTION ao bloco
PL/SQL para tratar as excepções em run time
 A segurar diferentes tipos de excepções:
 Pré-definidas
 Não pré-definidas
 Definidas pelo usuário
 A propagar excepções em blocos aninhados

186

93
UEM
Exercícios (1) DMI

1. Crie uma tabela mensagens com o atributo: msg VARCHAR2(100).

2. Na secção de declarações, declare duas variáveis: emp_nome do


tipo emp.ename e emp_sal do tipo emp.sal. Receba os valores de
emp_sal através de uma variável de substituição.

3. Na secção de execução, retorne os nomes dos emregados que


auferem um salário igual a emp_sal.
Não usar cursor explícito. Se para um dado valor de emp_sal for encontrado
apenas um registo, insira na tabela mensagens o nome do empregado e o
salario.

4. Se para um dado salário não for retornado nenhum valor, insira na


tabela mensagens o salário e o texto: “Nao existe empregado com
esse salário”.

187

UEM
Exercícios (2) DMI

5. Se para um dado salário retornar-se mais do que uma linha, segure a


excepção de modo mais coerente e insira na tabela mensagens o
salário e o texto: “Foi encontrada mais do que um registo”

6. Segure qualquer outro tipo de excepção que for a ocorrer e insira na


tabela mensagens: “Foi encontrado um erro desconhecido”.

7. Consulte a tabela mensagens

8. Altere a tabela mensagens e acrescente a coluna total_registos.


Refaça os exercícios anteriores de modo a inserir nesta nova coluna
o número total de registos encontrados.

188

94
UEM
Soluções (1) DMI

1. Create table mensagens(msg varchar2(100));

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;

INSERT into mensagens (msg) values (emp_nome||’-’||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

 Até agora todos os programas por nós desenvolvidos


são anónimos
 Como proceder para identificar os programas?
 Existe alguma necessidade de dar nomes aos
subprogramas?

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

 São blocos de PL/SQL nomeados (não anónimos)


 São sub-programas de PL/SQL chamáveis
 Possuem estrutura de blocos similar à estrutura dos
blocos anónimos:
 Há argumentos
 A secção de declarativa (DECLARE) é opcional
 A secção executável é obrigatória
 Á secção de tratamento de excepções (EXCEPTION) é
opcional
 Para a Função deve-se definir um valor de retorno
 O Procedimento pode retornar zero ou mais
valores 193

Diferenças entre Blocos UEM


Anónimos e Sub-programas DMI

Blocos Anónimos Sub-Programas


Blocos de PL/SQL sem nome Blocos de PL/SQL com nome
Compilado todas as vezes Compilados somente uma vez
Não armazenados na BD Armazenados na BD
Não podem ser invocado por outras aplicações Podem ser invocados por outras aplicações
Não retornam valores No caso de Função deve retornar valores
Não podem receber parâmetros Podem receber parâmetros
194

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;
/

SELECT * FROM dept;

 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

CREATE OR REPLACE FUNCTION check_sal RETURN Boolean IS


d_no emp.deptno%TYPE;
e_no emp.empno%TYPE;
salario emp.sal%TYPE;
sal_medio emp.sal%TYPE;
BEGIN
e_no := 7788;
SELECT sal, deptno INTO salario, d_no FROM emp WHERE empno = e_no;
SELECT AVG(sal) INTO sal_medio FROM emp WHERE deptno = d_no;
IF salario > sal_medio THEN RETURN TRUE;
ELSE RETURN FALSE;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
END;
/
198
SHOW ERRORS

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

Passagem de Parâmetro UEM


para uma Função DMI

CREATE OR REPLACE FUNCTION check_sal (e_no emp.empno%TYPE)


RETURN Boolean IS
d_no emp.deptno%TYPE;
salario emp.sal%TYPE;
sal_medio emp.sal%TYPE;
BEGIN
SELECT sal, deptno INTO salario, d_no FROM emp WHERE empno=e_no;
SELECT AVG(sal) INTO sal_medio FROM emp WHERE deptno=d_no;
IF salario > sal_medio THEN RETURN TRUE;
ELSE RETURN FALSE;
END IF;
EXCEPTION …

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

 O formando deverá ter aprendido:


 A criar procedimentos simples
 A invocar procedimentos a partir dum bloco
anónimo
 A criar funções simples
 A criar funções que recebam parâmetros
 A invocar funções a partir de blocos anónimos

203

UEM
Packages DMI

 Ao manipular e manter procedimentos e funções


que têm executam certas actividades relacionadas,
o uso de Packages é uma solução
 O caso de DBMS_OUTPUT, que é o Package mais
popular, tem vários procedimentos e funções

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

 Package Body – criam-se subprogramas


públicos e variáveis privadas
 Identificadores definidos no Package Body
são privados e não são visíveis fora do
Package Body
CREATE [OR REPLACE] PACKAGE BODY nome_de_package
IS ou AS
tipo privado e declarações de variáveis;
subprograma especificações;
END [nome_de_package];
207

Vantagens de uso de UEM


Packages DMI

 Facilidade de manutenção: encapsular-se logicamente


os programas relacionados. É fácil compreender cada
Package e interface.
 Facilita o desenho da aplicação: define interface
(estrutura) de programa sem código interior, antes
definir a estrutura da função na sua totalidade
 Informação escondida: construções públicas (visíveis
e acessíveis) ou privadas (escondidas e inacessíveis)
 Melhora o desempenho: quando se faz alusão
sucessiva a um subprograma encapsulado, este
package é carregado na memória da instância.
 Overloading (Sobrecarrega): pode-se atribuir mesmo
nome a procedimentos/funções diferentes no mesmo
Package sendo que, a diferença entre cada um destes
subprogramas resida apenas nos seus parâmetros. 208

104
Remoção de Packages e UEM
Body DMI

 Para remover o package especificado e


body, use as seguintes sintaxes:

DROP PACKAGE nome_de_package;

DROP PACKAGE BODY nome_de_package;

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

CREATE [OR REPLACE] TRIGGER {nome_de_trigger}


{BEFORE ou AFTER ou INSTEAD OF}
{INSERT ou UPDATE ou DELETE}
ON {nome_de_tabela ou nome_de_view}
[FOR EACH ROW]
[WHEN condição]
DECLARE

BEGIN

EXCEPTION

END;

211

Sintaxe de Trigger de DML UEM


(cont.) DMI

 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

 Trigger executado antes de linha inserir a tabela bonus


CREATE OR REPLACE TRIGGER tr_bonus
BEFORE INSERT ON BONUS;

 Trigger executado depois de linha inserir ou actualizar a tabela


bonus
CREATE OR REPLACE TRIGGER tr_bonus
AFTER INSERT OR UPDATE ON BONUS;

213

Criação de ROW trigger de UEM


DML DMI

CREATE OR REPLACE TRIGGER sal_trig


BEFORE INSERT OR UPDATE OF sal ON emp
FOR EACH ROW
BEGIN
IF NOT(:NEW.job IN (‘CLERK’, ‘SALESMAN’))
AND :NEW.sal > 5000 THEN
RAISE_APPLICATION_ERROR (-20202,
‘Empregado não pode ganhar mais do que $5000’);
END IF;
END;
/

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

EMPNO ENAME JOB SAL


7369 SMITH CLERK 800
:NEW.sal 7900 JAMES CLERK 950

:OLD.sal
215

Uso de qualificadores: UEM


OLD e NEW DMI

 Dentro do ROW Trigger, referimos valor de


coluna antes e depois de mudar dados por
qualificadores OLD e NEW
 Estes qualificadores são disponíveis somente
em ROW triggers

Operação de Dado Valor de OLD Valor de NEW


INSERT NULL Valor inserido
UPDATE Valor antes de UPDATE Valor depois de UPDATE
DELETE Valor antes de DELETE NULL

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

Tipo de Evento Evento Causa


CREATE Depois de Declaração de CREATE
DDL ALTER Depois de Declaração de ALTER
DROP Depois de Declaração de DROP
AFTER SERVERERROR Depois de erro de Servidor ser anotado
AFTER LOGIN Depois de usuário entrar na BD
BD BEFORE LOGOFF Antes de usuário sair da BD
AFTER STARTUP Depois de BD ser aberta
BEFORE SHUTDOWN Antes de BD ser terminada 217

UEM
Exemplo de Trigger de BD DMI

CREATE OR REPLACE TRIGGER logon_trig


AFTER LOGIN ON SCHEMA
BEGIN
INSERT INTO dept(deptno, dname, loc) VALUES(10, ‘COMERCIAL’, ‘MAPUTO’);
CALL emp_sal_proc(7788)
END;
/

 Palavra chave CALL


 Chamaremos procedimento armazenado
 Depois de CALL não se acrescenta ; (ponto e
vírgula) 218

109
UEM
Exercício (1) DMI

1. Modifique o código abaixo, por forma a criar um procedimento de nome


cumprimento que possa ser chamado a partir dum bloco anónimo. O procedimento
deve aceitar um argumento do tipo VARCHAR2, com o identificador nome. Esse
argumento deve substituir a palavra Mundo.

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;

Faça a chamada do procedimento criado.


219

UEM
Exercício (2) DMI

2. Faça uma função verifique se o resultado da consulta da existência


dum departamento fornecido pelos parâmetros é ou não verdadeiro.
Chame essa função a partir dum bloco anónimo.

220

110
UEM
Exercício (3) DMI

3. Criar um trigger que seja disparado antes de qualquer actualização


do salário dos gestores dos departamentos SALES e
OPERATIONS.

221

UEM
Soluções (1) DMI
SET SERVEROUTPUT ON
SHOW ERRORS

CREATE OR REPLACE PROCEDURE cumprimento (nome VARCHAR2) IS


hoje DATE:=sysdate;
amanha hoje%type;

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

Create OR REPLACE FUNCTION verifica_dept(deptnum dept.deptno%type) return


Boolean IS
numero dept.deptno%type;
BEGIN
SELECT deptno INTO numero FROM dept WHERE deptno = deptnum;
RETURN true;
EXCEPTION
WHEN no_data_found THEN
return false;
END;

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

SELECT d.deptno INTO deptSales FROM emp e, dept d WHERE e.deptno =


d.deptno AND d.dname = 'SALES';
SELECT d.deptno INTO deptOperations FROM emp e, dept d WHERE e.deptno =
d.deptno AND d.dname='OPERATIONS';

IF (:NEW.deptno IN (deptSales, deptOperations)) AND (:NEW.job IN


('MANAGER')) THEN
RAISE_APPLICATION_ERROR (-20500,'Aumento não permitido para este
gestor');
END IF; 224
END;

112
UEM
Questão DMI

 Um programa que foi feito em VB pode


chamar um Procedimento PL/SQL?
 Um programa que foi feito em Java pode
chamar um Procedimento PL/SQL?

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

Fechar Apagar Receber Executar


Conexão Parâmetro Valor retornado Declaração

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

' Criação de SQL


Set OraSqlStmt = OraDatabase.CreateSql("begin :ret
:= orcl.GetTmp(); end;", ORASQL_DEFAULT)
if OraDatabase.LastServerErr = 1008 then
OraDatabase.LastServerErrReset
if err <> 0 or OraDatabase.LastServerErr <> 0 then
MsgBox “Faltou a Criação de SQL"
end
end if

228

114
UEM
Chamado por Java DMI

 Uso de pacote de JDBC API


Import java.sql.*;

 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

Connection conn = null;


Statement stmt = null;
CallableStatement cstmt = null;
String sql_str = null;
String out1 = null;

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

Você também pode gostar