Você está na página 1de 58

Banco de Dados II

Apostila de
Programao de SGBD

Apostila elaborada pelo Professor Antonio Cesar de Barros Munari


Colaborao: Prof. Maria Anglica Calixto de Andrade Cardieri
Ago/2001

ndice
ndice................................................................................................................................................................2
I. Conceitos bsicos........................................................................................................................................4

pg: 2
D

Programao de SGBD

Introduo.....................................................................................................................................................4
II PL/SQL _ Estrutura Bsica..........................................................................................................................5
Estrutura de um bloco PL/SQL (annimo)..................................................................................................6
Tipos de sub-rotinas de banco de dados.......................................................................................................8
Procedimentos..........................................................................................................................................9
Funes.....................................................................................................................................................9
Gatilhos...................................................................................................................................................10
Diferena entre blocos annimos e sub-rotinas.........................................................................................10
Variveis, constantes e tipos de dados........................................................................................................12
Operadores..................................................................................................................................................13
Variveis especiais......................................................................................................................................13
Estruturas de controle de fluxo de programa.............................................................................................14
IF .. END IF............................................................................................................................................14
LOOP ... EXIT [WHEN ...] ... END LOOP...........................................................................................15
WHILE ... LOOP ... END LOOP...........................................................................................................15
FOR... IN ... LOOP ... END LOOP........................................................................................................16
III PL/SQL construes principais.................................................................................................................17
Cursores explcitos.................................................................................................................................18
Manipulao de erros.................................................................................................................................25
Triggers.......................................................................................................................................................27
IV Estudo de caso...........................................................................................................................................29
Exerccio proposto..................................................................................................................................42
ABS( <expN> ).......................................................................................................................................44
ADD_MONTHS( <expD>, <expN> )...................................................................................................44
ASCII( <expC> )....................................................................................................................................44
AVG([ DISTINCT | ALL] <expN> )......................................................................................................44
CEIL( <expN> ).....................................................................................................................................44
CHARTOROWID(<expC> )..................................................................................................................44
CHR( <expN> )......................................................................................................................................45
COUNT([DISTINCT | ALL] {* I <exp> })..........................................................................................45
CONVERT( <expC> [, destino[,fonte]])................................................................................................45
DECODE ( <exp> , <exp1> , <exp2>, [,<exp3>]).............................................................................45
DUMP( <exp> [,formato[, expl1[, expl2]]])..........................................................................................46
FLOOR( <expN> ).................................................................................................................................47
GREATEST( <exp>,...)..........................................................................................................................47
INITICAP( <expC> ).............................................................................................................................47
INSTR( <expC1>, <expC2> [, <expI> [,expI]])...................................................................................47
LAST_DAY( <expD> )..........................................................................................................................47
LEAST( <exp>,... )................................................................................................................................48
LENGTH( <expC> )..............................................................................................................................48
LOWER( <expC> )................................................................................................................................48
LPAD( <expC1> , <expI>[, <expC2>]).................................................................................................48
LTRIM( <expC1> [, <expC2>] )...........................................................................................................48
MAX( [ DISTINCT | ALL ] <exp> )......................................................................................................49
MIN( [ DISTINCT | ALL ] <exp> ).......................................................................................................49
MOD( <expN1>, <expN2> )..................................................................................................................49
MONTHS_BETWEEN( <expD1>, <expD2> ).....................................................................................49
NEW_TIME( <expD>, <expC1>, <expC2> ).......................................................................................49
NEXT_DAY( <expD>, expC )...............................................................................................................50
NLSSORT( <expC> ).............................................................................................................................50
NVL( <exp1>, <exp2> )........................................................................................................................50
POWER( <expN>, <n> )......................................................................................................................50
REPLACE( <expC1>, <expC2>[, <expC3>] )......................................................................................51
ROUND( <expD> [, formato ])..............................................................................................................51
ROUND( <expN> [, <expI> ] )..............................................................................................................51
ROWIDTOCHAR( <ROWID> )............................................................................................................51
RPAD( <expC1>, <expI> [,<expC2> )..................................................................................................52
RTRIM( <expC1> [,<expC2> )..............................................................................................................52

pg: 3
D

Programao de SGBD
SIGN( <expN> ).....................................................................................................................................52
SOUNDEX( <expC> )...........................................................................................................................52
SQRT( <expN> )....................................................................................................................................52
STDDEV ([ DISCTINT | ALL<expN>).................................................................................................53
SUBSTR( <expC> , <expI1> [,<expI2>)...............................................................................................53
SUM( [DISTINCT | ALL] <expN> ).....................................................................................................53
TO_CHAR( <expN> [, formato ])..........................................................................................................53
TO_CHAR( <expD> [, formato ])..........................................................................................................53
TO_DATE( <expC> [, formato ])...........................................................................................................54
TO_NUMBER( <expC> )......................................................................................................................54
TRANSLATE( <expC1> , <expC2>, <expC3>)...................................................................................54
TRUNC( <expN> [, n ] )........................................................................................................................54
TRUNC( <expD> [, formato ] ).............................................................................................................55
UPPER( <expC> )..................................................................................................................................55
USERENV( <opo> )...........................................................................................................................55
VARIANCE( [ DISTINCT | ALL ] <expN> )........................................................................................56
VSIZE( <exp> )......................................................................................................................................56
Converso de tipo de dados........................................................................................................................56
Lista Nmero 1...................................................................................................................................57
ento valorConsulta = VrHonor * 0.8....................................................................................58
Ento valorConsulta = VrHonor * 0.7....................................................................58
Lista Nmero 2...................................................................................................................................59

pg: 4

Programao de SGBD

I. Conceitos bsicos

Introduo
Um nmero muito grande de operaes pode ser executado sobre um banco de dados atravs de
comandos SQL. Algumas dessas operaes podem ser bastante complexas, envolvendo um grande nmero
de tabelas e consultas, com aninhamento de comandos inclusive. Esses recursos da SQL no so
suficientes, entretanto, para solucionar muitos problemas comerciais tpicos, uma vez que a SQL no
oferece recursos de programao estruturada, como loopings e desvios, por exemplo. Por esse motivo, os
principais fornecedores de SGBDs criaram suas prprias extenses procedurais SQL (como a PL/SQL no
Oracle ou a Transact SQL no SQL Server), de maneira a prover recursos de programao em seus
gerenciadores. Essas extenses so verdadeiras linguagens de programao embutidas no SGBD, porm
so proprietrias, ou seja, variam de um produto para outro, apesar de implementarem alguns conceitos
bsicos comuns.
Assim, temos a implementao da SQL nos diversos gerenciadores de banco de dados ocorrendo
basicamente em 3 nveis, conforme a figura a seguir:

Recursos SQL do SGBD

SQL padro

Extenses no
procedurais
SQL

Extenses
procedurais
SQL

No primeiro nvel, chamado de SQL padro na figura, h uma uniformidade na sintaxe de certos
recursos SQL, atravs de padronizaes internacionais controladas por rgos especiais como ANSI, ISO,
X-Open, etc. Entram nesta categoria uma grande parte dos comandos DML SQL, de maneira que a
sintaxe e o funcionamento de um SELECT por exemplo, tanto no Oracle como no SQL Server ou MSAccess so iguais para a maioria das consultas bsicas.
Para prover capacidades mais amplas em seus produtos, os fornecedores muitas vezes acrescentam
recursos adicionais ao mecanismo bsico, como por exemplo funes de agregao extras (para clculo de
desvio padro ou varincia, por exemplo), manipulao de strings, tipos de dados, tamanho de registro,
clusulas extras em comandos, etc. Esses recursos variam muito de um SGBD para outro, o que significa
que solues que os utilizem podem no funcionar em outros ambientes de banco de dados e so
representados na figura como Extenses no procedurais SQL.
O terceiro nvel, indicado como Extenses procedurais SQL representa a linguagem de
programao procedural suportada pelo SGBD, e constitui o tema desta apostila.
Com os recursos fornecidos pelas extenses procedurais dos gerenciadores de banco de dados
possvel construir rotinas de diversos tipos que funcionam dentro do SGBD, implementando operaes de
lgica mais complexa e capacidades de processamento linha a linha. Neste material utilizaremos como

pg: 5

Programao de SGBD

D
referncia o Oracle 7.3 Server e sua linguagem de programao, chamada PL/SQL (Procedural Language /
SQL).

II PL/SQL _ Estrutura Bsica


Como vimos, o PL/SQL uma extenso da linguagem SQL, que permite a construo de blocos de
comandos SQL para acesso e manipulao das bases de dados. Estes blocos podem estar estruturados de
duas formas:

Dentro de um arquivo texto na forma de um bloco annimo. Este tipo de bloco no cadastrado no
dicionrio de dados e sua execuo determinada atravs da chamada ao arquivo no qual ele se
encontra.
Declarado na forma de uma sub-rotina de banco de dados.

A programao atravs da linguagem procedural (PL/SQL) apresenta diversas vantagens destacando-se:


Permite a construo de mdulos: A construo em blocos quebra a complexidade de problemas
gerando um conjunto de mdulos lgicos, facilitando o gerenciamento. possvel a construo de blocos
aninhados.
Declarao de variveis: Declara variveis, constantes e excees que podem ser usadas em declaraes
procedurais e SQL.
Fluxo de Controle: Permite a utilizao de comandos de desvio condicionais e incondicionais e tambm
loops para seqncia de declaraes.
Tratamento de erros: Processa erros do servidor com rotinas de tratamento de excees, declara
condies de erro definidas pelo usurio e as processa pelas rotinas de tratamento de excees.
Portabilidade: Pode ser usado em qualquer plataforma que acesse um banco de dados Oracle.
Peformance: Pode aumentar o desempenho de aplicaes crticas por ser uma ferramenta integrada ao
Oracle.

Estrutura de um bloco PL/SQL (annimo)

pg: 6

Programao de SGBD

D
DECLARE

BEGIN

EXCEPTION

END;

Declare: rea opcional, destinada a declarao de variveis, constantes cursores e excees.


Begin: rea destinada a seqncia de comandos a serem executados. Contm declaraes SQL para
manipular dados no banco de dados e declaraes PL/SQL.
Exception: rea destinada ao tratamento de excees, isto erros e condies anormais que ocorrerem na
seo de execuo (begin).

Exemplo 1:
Declare
wcarga_horaria number(5);
Begin
select carga_horaria into wcarga_horaria
from curso
where cod_curso = 5;
if wcarga_horaria is null then
update curso
set carga_horaria = 72;
commit;
end if ;
exception
when no_data_found then
insert into tab_erro values ( valor no encontrado);
end;

Observaes:
As palavras chaves Begin, End e Declare no so seguidas de ponto e vrgula.
As regras de sintaxe PL/SQL so semelhantes s do SQL:
Linhas de comando podem ser subdivididas
No podem ser usadas palavras reservadas.
Identificadores devem comear com uma letra e conter at 30 caracteres.
Campos de caracteres e datas devem ser usados entre aspas simples.
Comentrios devem ser delimitados por /* * /
So permitidos os comandos select, insert, delete, update

pg: 7
D

Programao de SGBD

Exerccio:
Testar o bloco PL/SQL do exemplo acima.
Inicialmente defina as tabelas Curso e tab_erro.
Depois execute o bloco sem a existncia do curso com cod = 5.
Inclua o curso com cdigo 5 e teste novamente.

Tipos de sub-rotinas de banco de dados


Uma subrotina um mdulo de programa executado para uma determinada finalidade e
geralmente possui um nome, pode receber parmetros e, conforme o caso, devolver valores. Todas as
linguagens de programao atuais (estruturadas ou orientadas a objetos) suportam esse conceito. As
subrotinas de que tratamos aqui possuem, entretanto, uma caracterstica particular: elas so processadas
pelo gerenciador de banco de dados, de maneira que se comportam como se fossem parte dele. Em um
ambiente de banco de dados cliente / servidor, seria algo como o mostrado na figura a seguir:

pg: 8

Programao de SGBD

Usurio

Aplicao final

SGBD

Subrotina

Banco de Dados

Cliente

Servidor

Observe que a subrotina executada pelo SGBD, na mquina servidora, a pedido da estao
cliente.

pg: 9

Programao de SGBD

Existem 3 tipos bsicos de subrotinas de banco de dados: os procedimentos, as funes e os


gatilhos.

Procedimentos
Tambm chamados de procedimentos armazenados (stored procedures), representam pores de
cdigo SQL e no SQL que ficam armazenados de forma compilada no catlogo do SGBD e so ativados
explicitamente por aplicaes, triggers ou outras rotinas. Como nas linguagens tradicionais de
programao, um procedimento realiza um processamento qualquer e no devolve valor algum em seu
final.
Exemplo:
Ativao

Procedimento

EXEC CrDep(D8,COMPRAS)

CREATE PROCEDURE CrDep( p1 IN VARCHAR2, p2 IN VARCHAR2 ) AS


BEGIN
INSERT INTO Depto
VALUES ( p1, p2 ) ;
END ;

Neste material utilizaremos o termo Procedure para referenciar os procedimentos armazenados.

Funes
A exemplo das procedures, as funes contm pores de cdigo SQL e no SQL; ficam
armazenadas de forma compilada no catlogo do SGBD e so ativadas explicitamente por aplicaes,
triggers ou outras rotinas. A diferena bsica entre o procedimento e a funo que uma funo, ao
realizar um processamento, produz um valor que devolvido (retornado) em seu final.
Exemplo:
Ativao

Funo

INSERT INTO teste


VALUES (1, CalcDobro(1));

CREATE FUNCTION CalcDobro ( p1 IN NUMBER ) RETURN NUMBER IS

Ou
SELECT NmFunc,
CalcDobro( VrSalario )
FROM Funcionario ;

p2 NUMBER ;
BEGIN
p2 := p1 * 2 ;
RETURN p2 ;
END ;

pg: 10

Programao de SGBD

Gatilhos
Um gatilho (ou trigger) uma poro de cdigo composto por instrues SQL e no-SQL que
ficam armazenados no catlogo do SGBD e que so ativados automaticamente pelo gerenciador de banco
de dados quando um determinado evento ocorre. Em princpio um gatilho poderia ser entendido como
uma procedure ativada implicitamente pelo SGBD.
Exemplo:
Ativao

Gatilho

DELETE FROM Funcionario


WHERE NrMatric = 1029 ;

CREATE TRIGGER ApgFunc


BEFORE DELETE ON Funcionario
FOR EACH ROW
BEGIN
INSERT INTO LogFunc (DtOp, Usuario, Chave )
VALUES ( SYSDATE, USER, :old.NrMatric ) ;
END ;

Neste material utilizaremos o termo Trigger para referenciar os gatilhos de banco de dados.

Diferena entre blocos annimos e sub-rotinas


Sintaticamente, blocos de procedimentos e sub-rotinas so idnticos a blocos annimos observando-se
duas excees:
- A palavra DECLARE deve ser omitida em sub-rotinas e procedimentos. Neste caso a declarao
de variveis deve ser feita entre as palavras chave IS /AS e BEGIN.
- Funes devem conter um comando de retorno explcito.

Exemplo 2:
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023

CREATE OR REPLACE PROCEDURE AtuSalario (vDepto IN CHAR, vPerc IN NUMBER) AS


vData DATE ;
cCdOp CONSTANT CHAR( 1 ) := U ;

-- Codigo p/ Update

BEGIN
vData := SYSDATE ;
UPDATE Funcionario
SET VrSalario = VrSalario * vPerc, DtUltAlt = vData
WHERE CdDepto = vDepto ;
INSERT INTO LogFunc ( DtOp, Usuario, Chave, CdOp )
VALUES ( vData, USER, VRSALARIO, cCdOp ) ;
COMMIT ;
-- Tratamento de excecoes
EXCEPTION
WHEN NO_DATA_FOUND THEN
raise_application_error ( 0001, Depto nao cadastrado ) ;
WHEN VALUE_ERROR THEN
raise_application_error ( 0002, Salario invalido ) ;

1
0

pg: 11

Programao de SGBD

024
WHEN OTHERS THEN
025
raise_application_error ( 9999, Erro geral ) ;
026 END ;

Esse exemplo representa um mdulo PL / SQL tpico (uma procedure, no caso), e permite
visualizar 4 regies bsicas, conforme o esquema:
Assinatura da rotina

(opcional)

Linha 001

rea de declaraes

(opcional)

Linhas 003 e 004

rea de instrues

(obrigatria)

Linhas 006 a 017

rea de excees

(opcional)

Linhas 019 a 025

A primeira rea da a Assinatura da rotina, que contm a declarao do nome e do tipo da


subrotina, ou seja, se uma procedure, funo ou trigger, por exemplo. Tambm indica a lista de
parmetros que o mdulo recebe (se houver algum) e, caso seja uma funo, indica tambm a varivel que
conter o seu valor de retorno. A rigor, a assinatura seria apenas esse conjunto de informaes, mas na
linha inicial aparece tambm o comando CREATE necessrio para gerar a rotina no SGBD. Esta rea
opcional, pois podemos ter rotinas sem nome ( blocos annimos) executadas apenas uma vez via linha de
comando.
A segunda parte a rea de declaraes gerais, onde so definidas as variveis, constantes,
cursores e excees utilizadas pelo mdulo. opcional e, conforme o tipo da rotina, pode requerer seu
incio com a palavra reservada DECLARE, como nos casos dos blocos annimos e triggers, por exemplo.
Em seguida, temos a nica rea obrigatria de um mdulo, a rea de instrues (ou comandos).
nela que colocamos a lgica da rotina. Inicia-se com uma declarao BEGIN.
Finalmente, temos uma rea opcional chamada rea de excees, onde so colocadas instrues
para o tratamento de erros na rotina, de acordo com um mecanismo interno disponvel no SGBD e que
pode sofrer tambm algumas adaptaes por parte do programador.
Toda rotina termina com um END, de maneira a fechar o BEGIN inicial da rea de instrues.
Comentrios iniciam-se com os caracteres -- (dois hifens seguidos) e prosseguem at o fim da linha
atual, conforme pode ser observado nas linhas 4 e 18 do exemplo anterior.

Exerccio 2:

Com base no modelo da vdeo-locadora definido em aulas anteriores, calcular o valor da multa na
devoluo da locao, considerando R$2,00 reais por dia de atraso. Atualizar a tabela de locao (campo
valorloc acrescido do valor da multa). O nmero da locao deve ser passado como parmetro. Usar
exception para testar se o nmero da locao no existe gravando mensagem de erro (tab_erro).

Variveis, constantes e tipos de dados

1
1

pg: 12

Programao de SGBD

O conceito de varivel e de constante do PL / SQL o mesmo das outras linguagens estruturadas:


so regies de memria que possuem um nome definido pelo programador e podem conter valores de um
determinado tipo de dado. O contedo de uma varivel pode se modificar durante a execuo da rotina,
enquanto que o valor da constante permanece fixo. Os tipos de dados permitidos so os seguintes:
Tipo do Dado
NUMBER
BINARY_INTEGER

Subtipos
DEC,
DECIMAL,
DOUBLE,
PRECISION, FLOAT, INT, INTEGER,
NUMERIC, REAL, SMALLINT
NATURAL, POSITIVE

CHAR
VARCHAR2

CHARACTER, STRING
VARCHAR

DATE
BOOLEAN
RECORD
TABLE

Descrio
Permite criar variveis ou constantes que
armazenem nmeros fixos ou de ponto
flutuante com preciso de at 38 dgitos.
Indicado para a criao de variveis ou
constantes que armazenem nmeros
inteiros com sinal, de forma a acelerar
algumas operaes com inteiros no
Oracle. A faixa de valores vlidos vai de
-231-1 at 231-1.
Permite texto de tamanho fixo at 32Kb.
Permite texto de tamanho varivel de at
32Kb.
Utilizado para armazenar datas, horas,
minutos e segundos.
Indicado para valores lgicos TRUE e
FALSE.
Utilizado para construir tipos complexos
estruturados, como imagens de registros
de tabelas, por exemplo.
Utilizado para conter conjuntos de dados
com vrias ocorrncias.

possvel tambm utilizar os atributos especiais %TYPE e %ROWTYPE para fazer com que uma
varivel ou constante herde o tipo de dado de um campo ou registro de tabela. Observe os exemplos a
seguir.
Exemplo 1:
DECLARE
NmUser
TxUnica
DtSist
QtFunc
VrSalario
QtCaixas

VARCHAR2( 30 ) ;
CONSTANT INTEGER := 2 ;
DATE := SYSDATE ;
NUMBER( 5, 0 ) ;
Funcionario.VrSalario%TYPE ;
QtFunc%TYPE ;

Exemplo 2:
DECLARE
TYPE RegCargo IS RECORD
( CdCargo CHAR( 2 ) NOT NULL := 0 ,
NmCargo CHAR( 30 ));
vCargo

RegCargo

1
2

pg: 13

Programao de SGBD

D
Exemplo 3:
DECLARE
RegFunc

Funcionario%ROWTYPE ;

Exemplo 4:
DECLARE
TYPE TabNrMatr IS TABLE OF CHAR(4) INDEX BY BINARY_INTEGER
;
vNrMatr

TabNrMatr ;

Operadores
A tabela abaixo apresenta o conjunto de operadores do PL / SQL.
Operador
+
*
/
**
=
>
<
>=
<=
<>
^=
!=
||
:=
-/*
*/

Significado
Adio
Subtrao
Multiplicao
Diviso
Exponenciao
Igual a
Maior que
Menor que
Maior ou igual a
Menor ou igual a
Diferente de
Diferente de
Diferente de
Concatenao de caracteres
Atribuio
Incio de comentrio (at fim da linha)
Incio de comentrio
Final de comentrio

Variveis especiais
Em um ambiente de programao Oracle existem disponveis para o programador algumas
variveis especiais bastante interessantes para determinadas aplicaes.
Varivel
USER
SYSDATE
UID

Tipo de Dado
Caracter
Date
Caracter / Number

Contedo
Nome do usurio corrente
Data e hora atuais do sistema
Nmero de identificao do usurio corrente

1
3

pg: 14

Programao de SGBD

Quando for necessrio obter o valor de uma dessas variveis a partir de um comando SELECT que
no referencia diretamente nenhuma tabela ou view normal do banco de dados, deve-se indicar a tabela
especial DUAL na clusula FROM do comando, conforme o exemplo a seguir.
SELECT SYSDATE, USER FROM Dual ;

Estruturas de controle de fluxo de programa


So as estruturas bsicas que permitem compor uma lgica procedural em uma rotina, como os
desvios e repeties.

IF .. END IF
utilizado para permitir que o fluxo do programa seja desviado para um determinado ponto da
lgica, conforme o resultado de uma comparao feita. Existem 3 variaes desta estrutura, cobrindo
desde o caso mais simples at possibilidades de desvio mltiplo.
Variao 1: Desvio simples, sem clusula ELSE
IF <expL> THEN
<operao1> ;
...
<operaoN> ;
END IF ;

IF var1 > 10 THEN


var2 := var1 + 1 ;
var3 := var1 / 4 ;
END IF ;

Variao 2: Desvio simples, com clusula ELSE


IF <expL> THEN
<operao1>
...
<operaoN>
ELSE
<operao1>
...
<operaoN>
END IF ;

;
;
;

IF var1 > 10 THEN


var2 := var1 + 1 ;
var3 := var1 / 4 ;
ELSE
var2 := 0 ;
var3 := var1 / 2 ;
END IF ;

Variao 3: Desvio mltiplo


IF <expL1> THEN
<operao1> ;
...
<operaoN> ;
ELSIF <expL2> THEN
...
ELSIF <expLN> THEN
...
[ ELSE
<operao1> ;
...

IF vNota > 9 THEN


vConceito := E ;
ELSIF vNota > 8 THEN
vConceito := A ;
ELSIF vNota > 7 THEN
vConceito := B ;
ELSE
vConceito := C ;
END IF ;

1
4

pg: 15

Programao de SGBD

D
<operaoN> ; ]
END IF ;

LOOP ... EXIT [WHEN ...] ... END LOOP


uma estrutura de repetio simples, cuja sada indicada pela instruo EXIT. possvel testar a
condio de sada atravs de uma estrutura IF / END IF conforme o exemplo abaixo ou, como mais
recomendvel, atravs da clusula opcional WHEN na prpria instruo EXIT, conforme mostra o
segundo exemplo.
Sintaxe bsica:

Exemplo 1:

LOOP
<operao1> ;
...
<operaoN> ;
EXIT [ WHEN <expL> ] ;
<operaoN + 1> ;
...
END LOOP ;

...
LOOP
...
vCont := vCont + 1 ;
IF vCont > 10 THEN
EXIT ;
END IF ;
...
END LOOP ;
...
Exemplo 2:
...
LOOP
...
vCont := vCont + 1 ;
EXIT WHEN vCont > 10 ;
...
END LOOP ;
...

WHILE ... LOOP ... END LOOP


O ciclo de iteraes executado enquanto a condio da clusula WHILE for verdadeira.
Sintaxe bsica:

Exemplo:

WHILE <expL> LOOP


<operao1> ;
...
<operaoN> ;
END LOOP ;

...
vCont := 1 ;
WHILE vCont <= 10 LOOP
...
vCont := vCont + 1 ;
...
END LOOP ;
...

1
5

pg: 16

Programao de SGBD

FOR... IN ... LOOP ... END LOOP


O ciclo de iteraes executado um nmero predefinido de vezes, controlado por meio de um
contador.
FOR <varivel> IN <faixa> [REVERSE] LOOP
<operao1> ;
...
<operaoN> ;
END LOOP ;

...
FOR vCont IN 1 .. 10 LOOP
...
...
END LOOP ;
...

Observaes
A varivel utilizada para o controle do looping FOR criada automaticamente no incio da
estrutura, e por isso, no deve ser declarada explcitamente na rea de declaraes da rotina. O seu
incremento (ou decremento, se a clusula REVERSE for utilizada) tambm automtico. Operaes de
atribuio no podem ser feitas para essa varivel.

1
6

pg: 17

Programao de SGBD

III PL/SQL construes principais


Cursores
O cursor explcito uma rea de armazenamento de dados que tem por finalidade armazenar uma coleo
de linhas recuperadas por um select.
Existem dois tipos de cursores:
Implcito: Criado pelo PL/SQL para todos os comandos DML e consultas.
Explcito: So os declarados pelo usurio. So utilizados em consultas e permitem processar mltiplas
linhas de uma query.
Cursores implcitos:
Um cursor deste tipo implementado atravs da colocao da clusula INTO no SELECT,
conforme pode ser visto no exemplo a seguir.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015

CREATE OR REPLACE FUNCTION AchaFunc ( pNrMatric IN CHAR ) RETURN CHAR IS


vResult

CHAR( 4 ) ;

BEGIN
SELECT Funcionario.NrMatric
INTO vResult
FROM Funcionario
WHERE Funcionario.NrMatric = pNrMatric ;
RETURN vResult ;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 9999 ;
END ;

Observe na linha 007 a presena da clusula INTO, indicando que o valor retornado pelo comando
ser colocado na varivel vResult, declarada na rotina. Caso houvesse mais de um valor a ser colocado em
variveis, a clusula INTO deveria conter uma lista com os nomes de todas as variveis, separadas por
vrgula. Essas variveis deveriam aparecer em uma ordem compatvel com os campos projetados pelo
SELECT.
Dois cuidados bsicos devem ser tomados ao utilizar-se cursores implcitos:
as variveis que recebero os dados obtidos pelo SELECT devero ser declaradas com tipo igual
ao do campo correspondente na tabela, o que torna bastante indicado nesses casos utilizar o
atributo %TYPE ao declarar a varivel, para evitar problemas de incompatibilidade;
o comando deve retornar no mximo uma nica linha, seno uma exceo
TOO_MANY_ROWS ser gerada.
No h uma declarao formal do cursor, apenas das variveis a serem atualizadas pelo comando.

Cursores explcitos

1
7

pg: 18

Programao de SGBD

Os cursores explcitos so chamados dessa forma porque so declarados formalmente na rea de


declaraes do mdulo, ao contrrio do que ocorre com os cursores implcitos. So tipicamente mais
flexveis e poderosos que os cursores implcitos, podendo substitu-los em qualquer situao.
Para sua utilizao so necessrios alguns passos bsicos:
declarar o cursor ;
declarar as variveis que recebero os dados ;
abrir (uma espcie de preparao) o cursor na rea de instrues ;
ler os dados produzidos pelo cursor ;
fechar (desalocar a memria) do cursor.
O exemplo a seguir ilustra a utilizao de um cursor explcito equivalente quele utilizado para
demonstrar o cursor implcito. Analise as principais diferenas entre essa soluo e a anterior.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018

CREATE OR REPLACE FUNCTION AchaFunc ( pNrMatric IN CHAR ) RETURN CHAR IS


vResult
CHAR( 4 ) ;
CURSOR vCursor IS
SELECT Funcionario.NrMatric
FROM Funcionario
WHERE Funcionario.NrMatric = pNrMatric ;
BEGIN
OPEN vCursor ;
FETCH vCursor INTO vResult ;
IF vCursor%FOUND THEN
RETURN vResult ;
ELSE
RETURN 9999 ;
END IF ;
CLOSE vCursor ;
END ;

Inicialmente, existe a declarao do cursor nas linhas 004 a 007, onde no aparece a clusula
INTO. O nome dado ao cursor segue as mesmas regras para os nomes de variveis. A sintaxe bsica dessa
declarao a seguinte:
CURSOR <nome do cursor> IS <declarao SELECT> ;
Ao fazermos a declarao, apenas foi definida uma estrutura que ser utilizada posteriormente,
quando o SELECT for executado e a recuperao das linhas for realizada. A primeira instruo realmente
executvel relativa ao cursor a sua abertura, feita na rea de instrues atravs do comando OPEN. no
momento da abertura que o SELECT executado e as linhas recuperadas tornam-se disponveis para uso.
Sintaxe dos comandos:
Open:

Executa a query e deixa disponvel os valores trazidos para serem trabalhados.


Open <nome-do-cursor>;

Fetch: Para processar as linhas armazenadas no cursor, preciso carregar os valores da linha corrente em
variveis. A linha corrente aquela em que o cursor est posicionado. Cada fetch funciona como um
read pois faz com que o cursor mude a linha corrente para a prxima.
Fetch <nome-do-cursor> into <rea-de-trabalho>;
Close: Limpa a rea de trabalho do cursor liberando a memria.
Close <nome-do-cursor>;

1
8

pg: 19
D

Programao de SGBD

Exemplo 2 :
Create or replace procedure patraso
is
begin
--Procedure para gravar socios em atraso
Declare
wdatfecha Date := '19-SEP-97';
cursor locacoes is
Select s.cdsocio, l.nrlocacao, dtprevdev,
valorloc, valormulta from locacao l, socio s
where s.cdsocio = l.cdsocio
and datadev is null
and dtprevdev <= wdatfecha;
--- define um registro com os mesmos campos de locacoes
-reg_locacoes locacoes%rowtype;
-- declara algumas variveis
-wdiatraso number(3);
wval_total locacao.valorloc%type;
wval_multa locacao.valormulta%type;
Begin
open locacoes;
fetch locacoes into reg_locacoes;
while locacoes%found loop
wdiatraso := wdatfecha - reg_locacoes.dtprevdev;
wval_multa := 2 * wdiatraso;
wval_total := reg_locacoes.valorloc + wval_multa;
update locacao
set valorloc = wval_total
where locacao.nrlocacao = reg_locacoes.nrlocacao;
insert into tlog
( dat_log,dsc_mensagem) values
(wdatfecha,'Socio'|| to_char(reg_locacoes.cdsocio) ||
' em atraso - locacao' || to_char(reg_locacoes.nrlocacao));
fetch locacoes into reg_locacoes;
end loop;
commit;
close locacoes;
end;
end;
/
No exemplo acima usamos comandos que permitem que uma varivel herde a estrutura de dados de outra
varivel. So eles:
Atributo %TYPE => Usado para indicar que uma varivel declarada herdar o mesmo tipo de outra
varivel previamente declarada. Isto util quando no sabemos o tipo de uma determinada coluna do
banco de dados alm de permitir alterao da coluna do banco de dados em runtime.

1
9

pg: 20

Programao de SGBD

D
Exemplo:
Declare
wcodsocio socio.codsocio%type

Neste caso a varivel wcodsocio herda o tipo da coluna codsocio da tabela socio.
Atributo %ROWTYPE => Semelhante ao %type, porm declara uma varivel herdando uma estrutura
de dados do banco de dados
Exemplo:
Declare
socio-reg socio%rowtype
Reg-scio herda toda a estrutura da tabela scio.
Alm dos recursos bsicos ligados aos cursores, existem trs outros que merecem ateno: a
possibilidade da passagem de parmetros para os cursores; os chamados
atributos de cursor e cursores explcitos via looping FOR.

Parmetros de cursor
Geralmente o comando SELECT de um cursor possui uma clusula WHERE que especifica uma
seleo de linhas a serem retornadas. Muitas vezes, temos necessidade de variar um dado a ser comparado
nessa clusula, e isso pode ser feito atravs de uma espcie de parmetro passado para o cursor no
momento de sua abertura. Observe o exemplo a seguir:
001 DECLARE
002
vMatr CHAR( 4 ) ;
003
vNome VARCHAR2( 30 ) ;
004
CURSOR LstFunc ( pSexo CHAR ) IS
005
SELECT NrMatric, NmFunc
006
FROM Funcionario
007
WHERE Sexo = pSexo ;
008
009 BEGIN
010
OPEN LstFunc( F ) ;
011
FETCH LstFunc INTO vMatr, vNome ;
012
CLOSE LstFunc ;
013
014
OPEN LstFunc( M ) ;
015
FETCH LstFunc INTO vMatr, vNome ;
016
CLOSE LstFunc ;
017
018 END ;

Ao abrirmos pela primeira vez, na linha 10, o cursor assume F como sendo o contedo da varivel
pSexo, e assim, recupera apenas os funcionrios do sexo feminino. Na segunda vez que aberto, o
parmetro passado M, e apenas os funcionrios de sexo masculino so processados.

Atributos de cursor
Durante a utilizao de um cursor em uma rotina, uma srie de valores podem ser testados, de
maneira a permitir a monitorao do estado corrente do processamento. Esses valores so obtidos atravs
de variveis especiais mantidas pelo sistema, chamadas de Atributos do cursor. Todos eles tm seu nome
comeando com o smbolo % (sinal de porcentagem) e so referenciados colocando-se o nome do cursor
imediatamente antes do %. A seguir um pequeno resumo com esses atributos e suas caractersticas
principais.

2
0

pg: 21

Programao de SGBD

D
Atributo
%ISOPEN

Tipo de Dado
BOOLEAN

Descrio
Indica se o cursor referenciado est aberto (TRUE) ou fechado (FALSE).

%ROWCOUNT

NUMBER

um contador que indica quantas linhas j foram recuperadas atravs de


um comando FETCH.

%NOTFOUND

BOOLEAN

Indica o resultado do ltimo FETCH: se foi bem sucedido, seu valor


FALSE, seno TRUE

%FOUND

BOOLEAN

Indica o resultado do ltimo FETCH: se foi bem sucedido, seu valor


TRUE, seno FALSE.

Alguns exemplos de utilizao desses atributos de cursor:


Exemplo 1:
001 DECLARE
002
vMatr
CHAR( 4 ) ;
003
vSalario
Funcionario.VrSalario%TYPE ;
004
CURSOR TesteCur IS
005
SELECT NrMatric, VrSalario
006
FROM Funcionario ;
007
008 BEGIN
...
.. .
018
IF TesteCur%ISOPEN THEN
019
CLOSE TesteCur ;
020
ELSE
021
OPEN TesteCur ;
022
END IF ;
...
...
034 END ;

Exemplo 2:
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018

CREATE OR REPLACE FUNCTION AchaFunc ( pNrMatric IN CHAR ) RETURN CHAR IS


vResult
CHAR( 4 ) ;
CURSOR vCursor IS
SELECT Funcionario.NrMatric
FROM Funcionario
WHERE Funcionario.NrMatric = pNrMatric ;
BEGIN
OPEN vCursor ;
FETCH vCursor INTO vResult ;
IF vCursor%FOUND THEN
RETURN vResult ;
ELSE
RETURN 9999 ;
END IF ;
CLOSE vCursor ;
END ;

2
1

pg: 22

Programao de SGBD

D
Exemplo 3:

001 DECLARE
002
vMatr
CHAR( 4 ) ;
003
vSalario
Funcionario.VrSalario%TYPE ;
004
vTotSal
Funcionario.VrSalario%TYPE := 0 ;
005
CURSOR TesteCur IS
006
SELECT NrMatric, VrSalario
007
FROM Funcionario
008
ORDER BY VrSalario DESC ;
009
010 BEGIN
011
OPEN TesteCur ;
012
LOOP
013
FETCH TesteCur INTO vMatr, vSalario ;
014
EXIT WHEN TesteCur%NOTFOUND OR TesteCur%ROWCOUNT = 3 ;
015
vTotSal := vTotSal + vSalario ;
016
END LOOP ;
...
...
027
CLOSE TesteCur ;
028 END ;

2
2

pg: 23

Programao de SGBD

Cursores explcitos com looping FOR


Esta uma variao do cursor explcito em que este fica embutido em uma estrutura FOR
responsvel pelo seu processamento. uma espcie de simplificao, pois nessa estrutura o cursor aberto
uma vez, as linhas so processadas (uma a cada passagem do looping) e o cursor fechado
automaticamente no final das iteraes.
A sintaxe bsica a seguinte:
FOR <nome do registro> IN <nome do cursor> LOOP
... ;
... ;
END LOOP ;
O <nome do registro> um nome de varivel do tipo RECORD criada automaticamente na entrada
do looping. O cursor propriamente dito declarado normalmente na rea de declaraes da rotina, e pode
prever a utilizao de parmetros. Os atributos de cursor vistos anteriormente esto disponveis
normalmente neste tipo de estrutura.
Exemplo (com cursor explcito convencional):
001 DECLARE
002
vFunc
Funcionario%ROWTYPE ;
003
CURSOR CurFunc IS
004
SELECT *
005
FROM Funcionario ;
006
007 BEGIN
008
OPEN CurFunc ;
009
LOOP
010
FETCH CurFunc INTO vFunc ;
011
EXIT WHEN CurFunc%NOTFOUND ;
012
IF vFunc.VrSalario > 500 THEN
...
...
018
END IF ;
...
...
016
END LOOP ;
...
...
084
CLOSE CurFunc ;
085 END ;

Exemplo (com cursor explcito em looping FOR):


001 DECLARE
002
CURSOR CurFunc IS
003
SELECT *
004
FROM Funcionario ;
005 BEGIN
006
FOR vFunc IN CurFunc LOOP
007
IF vFunc.VrSalario > 500 THEN
...
...
014
END IF ;
...
...
040
END LOOP ;
...
...
084 END ;

2
3

pg: 24

Programao de SGBD

Manipulao de erros
Toda linguagem deve proporcionar aos programadores recursos para uma fcil e adequada
interveno em casos de erro de execuo, de maneira a minimizar ou evitar problemas maiores sobre os
dados. Em PL/SQL isso obtido atravs de um mecanismo baseado no conceito de excees, que podem
ser classificadas em internas ou externas. Uma exceo nada mais do que uma notificao de erro,
realizada pelo programa, atravs de um conjunto de cdigos previamente definidos, que podem ser
detectadas na rea de excees de um mdulo. Tendo sido detectada a ocorrncia, fcil para o
programador associar uma seqncia de instrues para o tratamento daquela espcie de erro.
Ao conjunto de excees padro previamente definidas para o PL/SQL damos o nome de excees
internas, que so mostradas no quadro a seguir.
Exceo
CURSOR_ALREADY_OPEN
DUP_VAL_ON_INDEX
INVALID_CURSOR
INVALID_NUMBER
LOGIN_DENIED
NO_DATA_FOUND
NOT_LOGGED_ON
PROGRAM_ERROR
STORAGE_ERROR
TIMEOUT_ON_RESOURCE
TOO_MANY_ROWS
TRANSACTION_BACKED_OUT
VALUE_ERROR
ZERO_DIVIDE

Descrio
Indica uma tentativa de se abrir um cursor j aberto no programa.
Tentativa de se inserir uma chave duplicada em uma coluna definida
como nica.
Referncia a cursor invlido ou tentativa de operao invlida sobre o
cursor.
Indica que um valor no numrico est sendo usado onde era esperado
apenas nmeros.
Solicitao de login negada
No foram encontrados dados para atender a uma requisio feita
atravs de SELECT INTO.
Usurio no est conectado no Oracle no momento (est off-line).
Erro interno do PL/SQL
Erro de memria do PL/SQL
Ocorreu o atingimento do tempo designado para o usurio na sua conta.
A instruo SELECT ... INTO encontrou mais de uma linha.
Um servidor remoto desfez a transao
Erro de aritmtica, de converso, truncagem ou de restrio.
Tentativa de se dividir um nmero por zero.

A deteco e o tratamento da condio de erro feita conforme mostrado na rotina criada a seguir.

2
4

pg: 25

Programao de SGBD

D
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026

CREATE OR REPLACE PROCEDURE AtuSalario (vDepto IN CHAR, vPerc IN NUMBER) AS


vData DATE ;
cCdOp CONSTANT CHAR( 1 ) := U ;

-- Codigo p/ Update

BEGIN
vData := SYSDATE ;
UPDATE Funcionario
SET VrSalario = VrSalario * vPerc, DtUltAlt = vData
WHERE CdDepto = vDepto ;
INSERT INTO LogFunc ( DtOp, Usuario, Chave, CdOp )
VALUES ( vData, USER, VRSALARIO, cCdOp ) ;
COMMIT ;
-- Tratamento de excecoes
EXCEPTION
WHEN NO_DATA_FOUND THEN
raise_application_error ( 0001, Depto nao cadastrado ) ;
WHEN VALUE_ERROR THEN
raise_application_error ( 0002, Salario invalido ) ;
WHEN OTHERS THEN
raise_application_error ( 9999, Erro geral ) ;
END ;

Geralmente, o procedimento adotado para o tratamento de uma exceo o cancelamento do


processamento, com a conseqente reverso de todas as operaes feitas na transao com problemas. Isso
pode ser obtido atravs da funo padro RAISE_APPLICATION_ERROR, que permite ainda retornar
um cdigo e uma mensagem de erro para a rotina chamadora do mdulo em que o problema ocorreu.

2
5

pg: 26

Programao de SGBD

Triggers
Um trigger, ou gatilho, de banco de dados uma rotina associada a uma tabela e que disparada
automaticamente sempre que um evento especfico ocorre. Rotinas deste tipo possuem uma estrutura
muito particular, que possvel esquematizar da seguinte forma:
TRIGGER <nome do trigger>
<BEFORE | AFTER> <evento de banco de dados>
[FOR EACH ROW]
[DECLARE
... ]
BEGIN
...
END ;
Um trigger criado atravs da instruo CREATE TRIGGER, e fica armazenado no catlogo do
SGBD, que o ativa a cada vez que o evento de banco de dados definido para ele ocorre. Esses eventos so
as operaes que provocam algum tipo de atualizao nos dados de uma tabela, ou seja, instrues
INSERT, UPDATE ou DELETE. Dentro de um trigger possvel declarar e utilizar variveis, constantes,
cursores, desvios e loopings, como em rotinas de outros tipos. Tambm possvel ativar outras rotinas
(procedures e functions) em seu interior.
Para uma melhor compreenso das caractersticas e recursos disponveis com os triggers, observe
os exemplos a seguir, procurando identificar o efeito de cada um deles e as condies em que so
disparados.
Exemplo 1:
Ativao

Trigger

DELETE FROM Funcionario


WHERE NrMatric = 1029 ;

CREATE TRIGGER ApgFunc


BEFORE DELETE ON Funcionario
FOR EACH ROW
BEGIN
INSERT INTO LogFunc (DtOp, Usuario, Chave )
VALUES ( SYSDATE, USER, :old.NrMatric ) ;
END ;

2
6

pg: 27

Programao de SGBD

D
Exemplo 2:
Ativao

Trigger

UPDATE Funcionario
SET VrSalario = VrSalario * 1.1
WHERE CdDepto IN ( D1,D3 );

CREATE TRIGGER AltSalFunc


AFTER UPDATE OF VrSalario ON Funcionario
DECLARE
CdOp
CONSTANT CHAR := S ;
BEGIN
INSERT INTO LogFunc (DtOp, Usuario, TpOp )
VALUES ( SYSDATE, USER, CdOp ) ;
END ;

Exemplo 3:
Ativao

Trigger

UPDATE Funcionario
CREATE TRIGGER AltSalFunc
SET VrSalario = VrSalario * 1.1; AFTER UPDATE OF VrSalario ON Funcionario
FOR EACH ROW
WHEN (new.VrSalario > 5000)
DECLARE
CdOp
CONSTANT CHAR := X ;
BEGIN
INSERT INTO LogFunc (DtOp, Usuario, TpOp )
VALUES ( SYSDATE, USER, CdOp ) ;
END ;

Exemplo 4:
Ativao

Trigger

UPDATE Cargo
SET NmCargo = OFICIAL ADMIN.
WHERE CdCargo = C4 ;

CREATE TRIGGER AltNmCargo


AFTER UPDATE OF NmCargo ON Cargo
FOR EACH ROW
BEGIN
INSERT INTO LogCargo
(DtOp, Usuario, ChOrig, ChNova )
VALUES ( SYSDATE, USER, :old.NmCargo,
:new.NmCargo ) ;
END ;

2
7

pg: 28

Programao de SGBD

IV Estudo de caso
Veremos agora um caso prtico que nos oferecer a oportunidade de utilizar alguns recursos muito
importantes de um gerenciador de banco de dados. Criao e alterao de tabelas, construo e utilizao
de rotinas no SGBD acompanhados de uma discusso sobre algumas questes pertinentes sobre o projeto
de bancos de dados so os tpicos que sero abordados, atravs do acompanhamento da evoluo de um
pequeno modelo de banco de dados para a manuteno de contas-corrente em um banco. O modelo
propositalmente simplificado, de maneira a ressaltar os tpicos centrais de nosso assunto: SQL Data
Definition Language e PL/SQL.
Inicialmente, o modelo a ser implantado seria o seguinte:

Observe que o modelo utiliza uma notao de modelagem de dados que combina a representao de
Peter Chen com uma forma particular de representao de cardinalidades. O projeto suporta contas
conjuntas, atravs do relacionamento N:N Mantm. Com isso, teremos 5 tabelas, correspondentes a cada
um dos arranjos de dados sugeridos no modelo:

2
8

pg: 29

Programao de SGBD

Entidade
Cliente
Mantm
Conta
Agncia
Movimento

Tabela
Cliente
CliConta
Conta
Agencia
Movimento

Utilizamos um arroba (@) para representar a chave primria de cada tabela e uma letra E para
designar cada uma das chaves estrangeiras. Todas as tabelas possuem uma chave primria simples, exceto
CliConta, que representa o relacionamento Mantm: nesse caso a chave primria composta, formada
pela combinao dos dois atributos (Cliente e Conta Corr.) que, individualmente, representam chaves
estrangeiras.
Alm dessas caractersticas, consideraremos ainda as seguintes especificaes adicionais sobre os
valores dos atributos:
Entidade
Cliente

Atributo
Nome
Endereo

Restries
obrigatrio, deve ser nico na tabela.
obrigatrio.

Agncia

Nome Agncia
Telefone

obrigatrio, deve ser nico na tabela.


obrigatrio.

Conta

Data Abertura
Agncia

obrigatrio.
obrigatrio.

Mantm

Cliente
Conta Corr.

obrigatrio.
obrigatrio.

Movimento

Conta Corr.
Data Movim.
Tipo Movim.
Valor Movim.
Descr. Movim.

obrigatrio.
obrigatrio.
obrigatrio, deve ser C ou D.
obrigatrio, deve ser maior que zero.
obrigatrio.

Alm de observar essas restries deveremos, para criar as tabelas, levar em conta os tipos de dados
mais adequados a cada atributo, bem como definir nomes de campos que sejam mnemnicos e guardem
alguma correspondncia com os nomes dos atributos, mas que tambm obedeam s regras de nomes
impostas pelo Oracle.

2
9

pg: 30

Programao de SGBD

Observe o script SQL que gera as tabelas correspondentes ao modelo no Oracle 7.3:
----------

*
*
Arquivo:
*
*
Autor:
*
*
Data:
*
* Finalidade:
*

CriaBan.sql
Cesar
20/3/97
Criar as tabelas referentes ao Banco Simplificado

CREATE TABLE Agencia


( CdAgencia
CHAR(4)
NmAgencia
VARCHAR2(30)
EndAgencia
VARCHAR2(50),
TelAgencia
VARCHAR2(15)
CREATE TABLE Cliente
( CdCliente
CHAR(5)
NmCliente
VARCHAR2(40)
EndCliente
VARCHAR2(50)
TelCliente
VARCHAR2(15),
RGCliente
VARCHAR2(15),
CPFCliente
VARCHAR2(15) ) ;
CREATE TABLE Conta
( NrConta
NUMBER(8)
DtAbertura
DATE
CdAgencia
CHAR(4)

PRIMARY KEY,
NOT NULL UNIQUE,
NOT NULL ) ;
PRIMARY KEY,
NOT NULL UNIQUE,
NOT NULL,

PRIMARY KEY,
NOT NULL,
NOT NULL
REFERENCES Agencia);

CREATE TABLE CliConta


( CdCliente
CHAR(5)
NOT NULL
NrConta
NUMBER(8)
NOT NULL
PRIMARY KEY (CdCliente, NrConta) ) ;

REFERENCES Cliente,
REFERENCES Conta,

CREATE TABLE Movimento


( NrMov
NUMBER(12)
NrConta
NUMBER(8)
DtMov
DATE
TpMov
CHAR(1)
VrMov
DsMov

PRIMARY KEY,
NOT NULL
REFERENCES Conta,
NOT NULL,
NOT NULL
CHECK ( TpMov IN( 'C', 'D' ) ),
NUMBER(12,2) NOT NULL
CHECK ( VrMov > 0 ),
VARCHAR2(20) NOT NULL ) ;

-- *
-- * Fim deste script
-- *
Voc deve ter reparado que existe uma ordem certa para criar as tabelas, uma vez que
especificamos as restries de integridade referencial (chaves estrangeiras) no prprio comando que cria
as tabelas. Dessa forma, primeiro temos que criar as tabelas que so referenciadas pelas demais. Se esse
cuidado no for tomado, um comando CREATE TABLE que declare uma chave estrangeira para uma
tabela ainda no existente ir falhar.

3
0

pg: 31

Programao de SGBD

Uma alternativa seria criar as tabelas apenas com as restries bsicas de NULL / NOT NULL.
Aps criadas todas as tabelas, seriam emitidos comandos ALTER TABLE que acrescentariam a cada
tabela as respectivas restries para implementar as outras regras de integridade (CHECK, UNIQUE,
PRIMARY KEY, FOREIGN KEY). Nesse caso, como ao especificar as chaves estrangeiras todas as
tabelas j existem, no h problema algum relacionado com a ordem das declaraes.
Suponhamos que comandos INSERT tenham sido emitidos para povoar com dados cada uma das
tabelas de nosso modelo. Os dados para estudo sero os seguintes:

SQL> SELECT * FROM Agencia;


CDAG
---0040
0050
0060

NMAGENCIA
---------------------Praca da Republica
Centro
Prefeitura

ENDAGENCIA
TELAGENCIA
------------------------------ ---------Praca da Republica, 200
555-4433
R 15 de Novembro, 800
555-2211
Av. Sao Paulo, 100
555-6612

3 rows selected.

SQL> SELECT CdCliente, NmCliente, EndCliente FROM Cliente;


CDCLI
----00001
00002
00003
00004
00005
00006
00007
00008
00009
00010

NMCLIENTE
-------------------------------ANA JUNQUEIRA
JOAO DA SILVA
MAIRA FIGUEIREDO
PEDRO SANTOS
SILVIO PADILHA
ROBERTO ARRUDA
SILVANA FERREIRA
CLAUDIA MARCONDES
JULIANO AGUILERA
MARIANA SOARES

ENDCLIENTE
-------------------------------R SALVADOR, 40
AV CAMPINAS, 89
R OLAVO BILAC, 430
R RUI BARBOSA, 230
R INCONFIDENTES, 20
R BAHIA, 140
AV 7 DE SETEMBRO, 2740
R SALVADOR DALI, 430
R PORTUGAL, 121
R CANDIDO PORTINARI, 1340

10 rows selected.

3
1

pg: 32

Programao de SGBD

D
SQL> SELECT * FROM Conta;
NRCONTA
--------1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032

DTABERTUR
--------10-AUG-95
01-SEP-95
12-SEP-95
23-OCT-95
25-OCT-95
04-NOV-95
10-NOV-95
12-NOV-95
17-NOV-95
26-NOV-95
08-DEC-95
12-DEC-95

CDAG
---0040
0060
0040
0050
0060
0050
0040
0050
0050
0040
0060
0060

12 rows selected.

SQL> SELECT * FROM CliConta;


CDCLI
NRCONTA
----- --------00001
1021
00002
1022
00003
1023
00004
1023
00005
1024
00006
1025
00007
1026
00002
1027
00008
1028
00004
1029
00009
1030
00010
1031
00001
1031
00005
1032
14 rows selected.

3
2

pg: 33
D

Programao de SGBD

SQL> SELECT * FROM Movimento;


NRMOV
NRCONTA DTMOV
T
VRMOV DSMOV
--------- --------- --------- - --------- -------------------1
1021 10-AUG-95 C
500 DEPOSITO
2
1022 20-SEP-95 C
750 DEPOSITO
3
1021 20-SEP-95 D
120 CHEQUE
4
1023 22-SEP-95 C
400 DEPOSITO
5
1024 10-OCT-95 C
920 DEPOSITO
6
1024 12-OCT-95 D
53 ORDEM DE PAGTO
7
1025 19-OCT-95 C
2100 DEPOSITO
8
1026 10-NOV-95 C
535 DEPOSITO
9
1021 12-NOV-95 D
100 CHEQUE
10
1022 20-NOV-95 D
80 CHEQUE
11
1027 10-DEC-95 C
100 DEPOSITO
12
1028 15-DEC-95 C
1500 DEPOSITO
13
1022 18-DEC-95 C
50 DEPOSITO
14
1023 18-DEC-95 D
250 CHEQUE
15
1029 19-DEC-95 C
1050 DEPOSITO
16
1030 20-DEC-95 C
500 DEPOSITO
17
1031 22-DEC-95 C
50 DEPOSITO
18
1021 22-DEC-95 C
50 DEPOSITO
19
1024 23-DEC-95 C
180 DEPOSITO
20
1021 27-DEC-95 C
238 DEPOSITO
20 rows selected.

Ao analisar a composio de cada tabela, esperamos que voc esteja imaginando como foram
escritos os comandos INSERT correspondentes. Voc tambm deve ter notado que o saldo de uma conta
corrente no se encontra disponvel explicitamente em lugar algum, mas pode ser obtido atravs de um
clculo. Essa soluo possvel mas no muito prtica. Suponha que queiramos acrescent-la, de
maneira que a recuperao desse valor no seja muito demorada. O melhor lugar para ela seria na tabela
de movimentos, conforme indicado na nova verso de nosso modelo Entidade / Relacionamento, mostrado
a seguir. O valor correspondente ao saldo dever ser calculado a cada alterao na base de dados e
colocado nesse novo campo, que mostrar assim o saldo atual da conta aps computado o movimento.
Evidentemente, o contedo do campo saldo no dever ser nulo em hiptese alguma para qualquer
movimento conhecido em qualquer conta.

3
3

pg: 34
D

Programao de SGBD

3
4

pg: 35

Programao de SGBD

Cliente

Mantm

@ Cd. Cliente

(E) Cliente

Nome

(E) Conta Cor

Endereo
Telefone
CPF
RG

3
5

pg: 36
D

Programao de SGBD

A implementao da alterao em nossa base de dados ser feita, em princpio, atravs de um


comando ALTER TABLE. Entretanto, devido ao fato de que o valor da nova coluna dever ser calculado e
que a tabela j conter dados no momento em que for alterada, um certo plano de ao se impe de forma
que algumas questes importantes sejam resolvidas no processo de atualizao da base de dados:
a) o novo campo dever ser criado inicialmente sem a clusula NOT NULL, uma vez que o valor
do saldo para cada linha da tabela de movimentos ser calculado posteriormente;
b) dever ser criado um procedimento que percorra a tabela de movimentos de ponta a ponta e
atualize os saldos com os valores corretos;
c) atualizada a coluna de saldo para as linhas pr-existentes na tabela, ser necessrio emitir um
novo comando ALTER TABLE, para acrescentar a clusula NOT NULL nova coluna;
d) finalmente, dever ser criado um trigger de banco de dados, de maneira que o valor
correspondente ao saldo seja calculado a cada alterao na tabela de movimentos.

3
6

pg: 37

Programao de SGBD

Basicamente, os comandos a serem emitidos so os seguintes:

SQL> ALTER TABLE Movimento ADD ( VrSaldo NUMBER( 12, 2 ) );


Table altered.
SQL>

Esse comando cria a nova coluna na tabela. O script a seguir cria o procedimento que ficar
armazenado no SGBD e quando ativado, calcular e atualizar o valor do saldo para cada movimento.
---------

*
*
Arquivo: CriProc0.sql
*
Autor: Cesar
*
Data: 2/9/97
* Finalidade: Exemplo de procedimento de banco de dados
*
(no caso, o procedimento AtuSaldoMov p/ atualizar
*
o saldo de uma conta na tabela de movimentos)
*

CREATE OR REPLACE PROCEDURE AtuSaldoMov AS


-- *
-- * Atualiza a coluna do saldo da conta na tabela de movimentos
-- *
-- * Declaracoes das variaveis
vNrConta Conta.NrConta%TYPE
vNrMov
Movimento.NrMov%TYPE
vTpMov
Movimento.TpMov%TYPE
vVrMov
Movimento.VrMov%TYPE
vVrSaldo Movimento.VrSaldo%TYPE

;
;
;
;
;

-- *
-- * Cursores p/ obter as contas a processar e seus movimentos
-- *
CURSOR CursorContas IS
SELECT Conta.NrConta
FROM Conta
ORDER BY Conta.NrConta ;
CURSOR CursorSaldoMov IS
SELECT Movimento.NrMov, Movimento.TpMov, Movimento.VrMov
FROM Movimento
WHERE Movimento.NrConta = vNrConta
ORDER BY Movimento.NrMov ;
-- * Corpo do procedimento
BEGIN
OPEN CursorContas ;
LOOP

3
7

pg: 38

Programao de SGBD

FETCH CursorContas INTO vNrConta ;


EXIT WHEN CursorContas%NOTFOUND ;
vVrSaldo := 0 ;
-- * Atualiza o novo campo na tabela Conta
OPEN CursorSaldoMov ;
LOOP
FETCH CursorSaldoMov INTO vNrMov, vTpMov, vVrMov ;
EXIT WHEN CursorSaldoMov%NOTFOUND ;
IF vTpMov = 'C' THEN
vVrSaldo := vVrSaldo + vVrMov ;
ELSE
vVrSaldo := vVrSaldo - vVrMov ;
END IF;
UPDATE Movimento
SET Movimento.VrSaldo = vVrSaldo
WHERE Movimento.NrMov = vNrMov ;
END LOOP ;
CLOSE CursorSaldoMov ;
END LOOP ;
CLOSE CursorContas ;
END AtuSaldoMov ;
-- *
-- * Fim do procedimento
-- *
O script cria no servidor de banco de dados uma rotina do tipo procedure chamada AtuSaldoMov.
Ela utiliza dois cursores, um para obter os nmeros de conta corrente a processar e outro para obter os
dados dos movimentos da conta. O valor do saldo calculado com base no saldo anterior, tipo de
movimento e valor do movimento. O resultado colocado na coluna do saldo atravs de um comando
UPDATE. Dois loopings so necessrios nessa lgica: um para processar todas as contas, outro para
processar todos os movimentos de uma conta. A lgica utilizada relativamente simples, mas a execuo
desse procedimento pode ser demorada, pois ele causa um grande trfego na rede. Felizmente, para
finalidades prticas, essa rotina dever ser executada apenas uma vez mesmo. O comando para que ela
seja executada seria o seguinte no prompt do SQL *Plus:

SQL> EXEC AtuSaldoMov


PL/SQL procedure successfully completed.
SQL>
Com a tabela atualizada, vamos ento tornar obrigatrio o fornecimento de um valor para a coluna
do saldo.

3
8

pg: 39

Programao de SGBD

SQL> ALTER TABLE Movimento MODIFY ( VrSaldo NOT NULL ) ;


Table altered.
SQL>

Resta ento criar o trigger de banco de dados para que o valor de saldo seja calculado a cada
alterao ou incluso na tabela de movimentos. Isso feito atravs do script a seguir, que implementa a
lgica apenas para o caso de incluso na tabela, ficando como exerccio alter-lo para que preveja tambm
a possibilidade de alterao.
-------

*
*
Arquivo:
*
Autor:
*
Data:
* Finalidade:
*

CriTrig1.sql
Cesar
30/3/97
Criar um exemplo de gatilho de banco de dados

CREATE OR REPLACE TRIGGER AtuSaldoInclusao


-- *
-- * Calcula o novo saldo com base no saldo anterior e no valor
-- * e tipo do movimento atual
-- *
-- * Instrucao de gatilho
BEFORE INSERT ON Movimento
-- * Linha de disparo
FOR EACH ROW
-- * Declaracoes de dados
DECLARE
-- * Variavel p/ armazenar o saldo original da conta
VrSaldoAnterior Movimento.VrSaldo%TYPE ;
-- * Cursor p/ obter o saldo original da conta
CURSOR CursorSaldoMov IS
SELECT VrSaldo
FROM Movimento
WHERE Movimento.NrConta = :new.NrConta
ORDER BY Movimento.NrMov DESC ;
-- * Corpo do gatilho
BEGIN
-- * Abrindo o cursor
OPEN CursorSaldoMov ;
-- * Obtendo a 1a linha (c/ movimento mais recente da conta)
FETCH CursorSaldoMov INTO VrSaldoAnterior ;
IF CursorSaldoMov%NOTFOUND THEN

3
9

pg: 40

Programao de SGBD

-- * Primeiro movimento na conta, saldo original e zero


VrSaldoAnterior := 0 ;
END IF ;
-- * Fechando o cursor
CLOSE CursorSaldoMov ;
-- * Calculando o novo saldo
IF :new.TpMov = 'C' THEN
:new.VrSaldo := VrSaldoAnterior + :new.VrMov ;
ELSE
:new.VrSaldo := VrSaldoAnterior - :new.VrMov ;
END IF ;
END AtuSaldoInclusao ;
-- *
-- * Fim deste script
-- *

4
0

pg: 41
D

Programao de SGBD

Exerccio proposto
Agora, vamos assumir que estudos concluram ser interessante desnormalizar a base de dados,
colocando o valor do saldo tambm na tabela de conta correntes. Essa alterao tornaria mais simples a
operao de consulta ao saldo de uma conta, minimizando o trfego na rede e a carga no servidor, mas
acrescentando uma maior complexidade nas operaes de atualizao da tabela de movimentos, pois o
novo valor do saldo deve ser atualizado tambm na tabela de contas. Assim, descreva o procedimento, os
comandos e as rotinas a serem criadas para implementar esse novo requisito. Como auxlio, fornecemos o
novo modelo Entidade / Relacionamento.

4
1

pg: 42

Programao de SGBD

Cliente

Mantm

@ Cd. Cliente

(E) Cliente

Nome

(E) Conta Cor

Endereo
Telefone
CPF

4
2

pg: 43

Programao de SGBD

Funes pr-definidas
ABS( <expN> )
Retorna o valor absoluto (nmero sem sinal) de expN.
Exemplo:
SELECT ABS( -1 ) FROM Dual ;

/* Resultado: 1 */

ADD_MONTHS( <expD>, <expN> )


Retorna a data expD acrescida de expN meses.
Exemplo:
SELECT ADD_MONTHS(SYSDATE, 6 ) FROM Dual ; /* Resultado: 16-SEP-98 */

ASCII( <expC> )
Retorna o valor ASCII do primeiro caracter de expC.
Exemplo:
SELECT ASCII(CdDepto) FROM Depto
WHERE CdDepto = D1 ; /* Resultado: 68 */

AVG([ DISTINCT | ALL] <expN> )


Retorna a mdia de expN. Os valores nulos so ignorados.
Exemplo:
SELECT AVG(VrSalario) FROM Funcionaro ;

/* Resultado: 1222*/

CEIL( <expN> )
Retorna o maior inteiro maior que ou igual a expN.
Exemplo:
SELECT CEIL(12.33) FROM DUAL ; /* Resultado: 13*/

CHARTOROWID(<expC> )
Retorna a expC convertido em um valor de ROWID.
O contedo da expC deve estar no formato da pseudo-coluna ROWID.
Exemplo:

4
3

pg: 44

Programao de SGBD

SELECT CHARTOROWID(NrMatric) FROM Funcionaro


WHERE NrMatricCDFUNC = 1001 ;
/*Resultado:
0001001.0000.0000*/

CHR( <expN> )
Retorna o caracter ASCII referente ao valor expN.
Exemplo:
SELECT CHR(75) FROM DUAL ;

/* Resultado: K*/

COUNT([DISTINCT | ALL] {* I <exp> })


Retorna o nmero de linhas da exp (ignora os valores nulos)
O * retorna o nmero de todas as linhas incluindo os valores nulos.
Exemplo:
SELECT COUNT( * ) FROM Funcionario ; /* Resultado: 21 */

CONVERT( <expC> [, destino[,fonte]])


Converte expC referente ao conjunto de caracteres fonte para o conjunto de caracteres destino.
Conjuntos disponveis para destino e fonte:
US7ASCII
Default, conjunto de caracteres ASCII US 7-bits.
WE8DEC
Conjunto de caracteres ASCII 8 bit-DEC.
WE8HP
Conjunto de caracteres ASCII 8 bit-HP.
F7DEC
Conjunto de caracteres ASCII 7 bit DEC frana.
WEIBMPC
Conjunto de caracteres ASCII 8-bit do IBM PC.
Exemplo:
SELECT CONVERT(convertido, US7ASCII, WE8HP ) FROM Dual ;
/* Resultado: convertido */

DECODE ( <exp> , <exp1> , <exp2>, [,<exp3>])


Caso a exp seja igual a exp1 retorna exp2, caso contrrio, retorna exp3, se exp3 for omitido,
retorna nulo se nenhuma condio for satisfeita.
Exemplo:
SELECT DECODE(CdDepto, D1, ADMINISTRACAO, NOT OK) FROM Depto
WHERE CDDepto = D1 ;
/* Resultado: ADMINISTRACAO */

4
4

pg: 45

Programao de SGBD

DUMP( <exp> [,formato[, expl1[, expl2]]])


Exibe o valor da exp em um formato interno especificado pelo parmetro formato, comeando na
posico expl1, com tamanho de expl2. Formato : Typ=n Len=m: lista de valore caracter a caracter ou
dgito a dgito.
n
Tipo de exp
1=Coluna de tipo de dado caractere ;
2=Coluna de tipo de dado numrico ;
12=Coluna de tipo de dado data e hora ;
23=Coluna de tipo de dado RAW ;
96= Sequncia de caracteres.
m
Tamanho de exp em caracteres ou dgitos (sem o ponto decimal);
Exemplo:
SELECT DUMP(NrMatric,4) OCTAL FROM Funcionario
WHERE CdDepto = 'D1' AND CdCargo = 'C1';
/* Resultado: Typ=96 Len=4: 54,49,54,54 */

4
5

pg: 46

Programao de SGBD

FLOOR( <expN> )
Retorna o menor inteiro igual a ou menor que expN.
Exemplo:
SELECT FLOOR( 12.8 ) FROM Dual ;

/* Resultado: 12 */

GREATEST( <exp>,...)
Retorna o maior valor de uma lista de valores exp.
Exemplo:
SELECT GREATEST(abcd, 123, defg ) FROM Dual ; /* Resultado: defg */

INITICAP( <expC> )
Retorna a expC com a primeira letra de cada palavra em maiscula e o resto da palavra em
minsculas.
Exemplo:
SELECT INITICAP(NmFunc) FROM Funcionario
WHERE NrMatric = 1004 ; /* Resultado: Lucio Torres */

INSTR( <expC1>, <expC2> [, <expI> [,expI]])


Retorna a posio da n-sima ocorrncia de expC2 dentro de expC1, comeando a pesquisa na
posio expN1 e qual ocorrncia expN2 a ser encontrada
Exemplo:
SELECT NmFunc, INSTR( NmFunc, A, 10, 1) FROM Funcionario
WHERE CdFunc = 1001; /* Resultado: 10 */

LAST_DAY( <expD> )
Retorna a data do ltimo dia do ms contida na data expD.
Exemplo:
SELECT LAST_DAY( SYSDATE ) FROM Dual ;

/* Resultado: 31-MAR-98 */

4
6

pg: 47

Programao de SGBD

LEAST( <exp>,... )
Retorna o menor valor de uma lista de valores exp.
Exemplo:
SELECT LEAST( abc,123,defg ) FROM Dual ;

/* Resultado: 123 */

LENGTH( <expC> )
Retorna o nmero de caracteres em expC
Exemplo:
SELECT LENGTH( NmDepto ) FROM Depto
WHERE CdDepto = D1 ; /* Resultado: 13 */

LOWER( <expC> )
Retorna todas as letras da expC em minsculas.
Exemplo:
SELECT LOWER( NmCargo ) FROM Cargo
WHERE CdCargo = C1;
/* Resultado: cozinheira */

LPAD( <expC1> , <expI>[, <expC2>])


Retorna a expC1 preenchido esquerda com exprI caracteres de expC2. Se expC2 for omitido,
retorna preenchido em brancos.
Exemplo:
SELECT LPAD( valor,8, *) FROM Dual ;

/* Resultado: ***valor */

LTRIM( <expC1> [, <expC2>] )


Elimina todos os caracteres esquerda
Exemplo:
SELECT ABS( -1 ) FROM Dual ;

/* Resultado: 1 */

4
7

pg: 48

Programao de SGBD

MAX( [ DISTINCT | ALL ] <exp> )


Retorna o maior valor de exp.
Exemplo:
SELECT MAX( VrSalario ) FROM Funcionario ; /* Resultado: */

MIN( [ DISTINCT | ALL ] <exp> )


Retorna o menor valor de exp.
Exemplo:
SELECT MIN( VrSalario ) FROM Funcionario ; /* Resultado: 1 */

MOD( <expN1>, <expN2> )


Retorna o resto da diviso de expN1 por expN2
Exemplo:
SELECT MOD( 10, 3 ) FROM Dual ; /* Resultado: 1 */

MONTHS_BETWEEN( <expD1>, <expD2> )


Retorna o nmero de meses entre as datas expD1 e expD2.
Exemplo:
SELECT MONTHS_BETWEEN( 20-FEB-91, 01-JAN-91 ) FROM Dual ;
/* Resultado: 1.6129 */

NEW_TIME( <expD>, <expC1>, <expC2> )


expD.

Retorna a data e a hora da zona expC2 quando a data e a hora da zona expC1 estiver na data e hora
Exemplo:

SELECT
TO_CHAR(
NEW_TIME(TO_DATE(20:16,hh24:mi),PST,GMT),
hh24:mi ) FROM Dual ; /* Resultado: 04:16 */

4
8

pg: 49

Programao de SGBD

NEXT_DAY( <expD>, expC )


Retorna a data do primeiro dia da semana expC igual a ou posterior a expD.
Exemplo:
SELECT NEXT_DAY( 27-OCT-94, SUNDAY ) FROM Dual ;
/* Resultado: 30-OCT-94 )*/

NLSSORT( <expC> )
Retorna um valor sequencial de expC referente a linguagem nacional utilizada pelo sistema.
Quando a ordem sequencial baseada em valores numricos dos caracteres. Esta ordem chamada ordem
binria.
Exemplo:
SELECT NLSSORT( A ) FROM Dual ;

/* Resultado: 4100 */

NVL( <exp1>, <exp2> )


Retorna exp2 caso exp1 seja nulo, seno retorna exp1.
Exemplo:
SELECT NVL( VrSalario, 0 ) FROM Funcionario
WHERE CdDepto = D2 ;

POWER( <expN>, <n> )


Retorna o valor expN elevado a n-sima potncia.
Exemplo:
SELECT POWER( 2, 6 ) FROM Dual ;

/* Resultado: 64 */

4
9

pg: 50

Programao de SGBD

REPLACE( <expC1>, <expC2>[, <expC3>] )


Retorna expC1 com todas as ocorrncias de caracteres de expC2, substituidas pelos caracteres de
expC3. Se expC3 for omitido , elimina todas a ocorrncias de expC2.
Exemplo:
SELECT REPLACE( ROMEU, EU, ARIA ) FROM Dual ;
/* Resultado: ROMARIA*/

ROUND( <expD> [, formato ])


Retorna a expD arrendondado como especificado pelo parmetro formato
Exemplo:
SELECT ROUND( TO_DATE( 27-OCT-97), YEAR) FROM Dual ;
/* Resultado: 01-JAN-98 */

ROUND( <expN> [, <expI> ] )


Retorna a expN arrendondado para a expI casas decimais; se expI for negativo, arredonda a direita
do ponto decimal, se expI for zero, arredonda para o valor inteiro mais prximo.
Exemplo:
SELECT ROUND( 153.452, 2) FROM DUAL ; /* Resultado: 153.45 */
SELECT ROUND( 153.452, -2) FROM DUAL ;
/* Resultado: 200 */
SELECT ROUND( 153.452) FROM DUAL ;
/* Resultado: 153 */

ROWIDTOCHAR( <ROWID> )
Converte o valor ROWID para um valor tipo caracter.
Exemplo:
SELECT ROWID FROM Funcionario
WHERE ROWIDTOCHAR(ROWID) LIKE %5AE1%;

/* Resultado:no rows selected */

5
0

pg: 51

Programao de SGBD

RPAD( <expC1>, <expI> [,<expC2> )


Retorna expC1 preenchido direita com expI caracteres de expC2. Se expC2 for omitido, retorna
preenchido com branco.
Exemplo:
SELECT RPAD( VALOR, 8, * ) FROM Dual ; /* Resultado: VALOR*** */

RTRIM( <expC1> [,<expC2> )


Elimina todos os caracteres esquerda de expC1 iguais ao primeiro caracter de expC2. Se expC2
for omitido, elimina os caracteres em branco.
Exemplo:
SELECT RTRIM( ABCD999, 9 ) FROM Dual ; /* Resultado: ABCD */

SIGN( <expN> )
Se expN for negativo retorna -1, se for positivo retorna 1, se for zero retorna 0.
Exemplo:
SELECT SIGN( 5432 ) FROM Dual ; /* Resultado: 1 */

SOUNDEX( <expC> )
Retorna uma representao fontica de cada palavra em expC (usa fontica da lingua inglesa).
Exemplo:
SELECT nome FROM TABELA
WHERE SOUNDEX( nome ) = SOUNDEX( SMYTH);

/* Resultado: SMITH */

SQRT( <expN> )
Retorna a raiz quadrada da expN, se expN for negativa, retorna nulo.
Exemplo:
SELECT SQRT( 144 ) FROM Dual ; /* Resultado: 12 */

5
1

pg: 52

Programao de SGBD

STDDEV ([ DISCTINT | ALL<expN>)


Retorna o desvio padro de expN. Valores nulos so ignorados
Exemplo:
SELECT STDDEV( VrSalario ) FROM Funcionario ;

/* Resultado: 555.90267

*/

SUBSTR( <expC> , <expI1> [,<expI2>)


Retorna a parte de expC, comeando na posio expI1 com tamanho de expI2.
Exemplo:
SELECT SUBSTR( ABCDF, 2,3 ) FROM Dual;

/* Resultado: BCD */

SUM( [DISTINCT | ALL] <expN> )


Retorna a soma dos valores de expN. Valores nulos so ignorados.
Exemplo:
SELECT SUM( VrSalario ) FROM Funcionario ; /* Resultado: 7750 */

TO_CHAR( <expN> [, formato ])


Converte o valor expN de tipo de dado numrico para um valor do tipo de dado caracter no formato
especificado pelo parmetro formato.
Exemplo:
SELECT TO_CHAR( 194 , 09999 ) FROM Dual ; /* Resultado: 00194 */

TO_CHAR( <expD> [, formato ])


Converte o valor expD de tipo de dado DATE para um valor do tipo de dado caracter no formato
especificado pelo parmetro formato.
Exemplo:
SELECT TO_CHAR(SYSDATE, DD ) FROM Dual ; /* Resultado: 17 */

5
2

pg: 53

Programao de SGBD

TO_DATE( <expC> [, formato ])


Converte a data/hora expC que esta no tipo de dado caracter formato especificado pelo parmetro
formato, para um valor no tipo de dado DATE.
Exemplo:
SELECT TO_DATE( 15/JAN/98 ) FROM Dual ;/* Resultado:15-JAN-98*/

TO_NUMBER( <expC> )
Converte um nmero do tipo caracter para o tipo de dado numrico.
Exemplo:
SELECT TO_NUMBER( SUBSTR(ABCD00193,5,5) )
FROM Dual ;
/* Resultado: 193 */

TRANSLATE( <expC1> , <expC2>, <expC3>)


Retorna expC1 substituido com todas as ocorrncias de expC2 com o caracter correspondente em
expC3.
Exemplo:
SELECT TRANSLATE( MARIO, O,A ) FROM Dual ;/* Resultado: */

TRUNC( <expN> [, n ] )
Retorna expN truncado na n-sima casa decimal; se for omitido ou for zero, trunca para o valor
inteiro, se n for negativo , zera o dgito esquerda do ponto decimal.
Exemplo:
SELECT TRUNC( 785.143 ) FROM Dual ; /* Resultado: 785 */
SELECT TRUNC( 785.14, -2 ) FROM Dual ;
/* Resultado:100 */

5
3

pg: 54

Programao de SGBD

TRUNC( <expD> [, formato ] )


Retorna expD truncado como especificado no parmetro formato.
Exemplo:
SELECT TRUNC( 785.143 )
FROM Dual ;
/* Resultado: 785 */

UPPER( <expC> )
Retorna a expC com todas as letras em maisculas
Exemplo:
SELECT UPPER( NmDepto )
FROM Depto
WHERE CDDEPTO = D1; /* Resultado: ADMINISTRACAO */

USERENV( <opo> )
Retorna informaes da opo escolhida sobre o usurio e/ou a seo corrente.
Opes :
ENTRYIDIdentificador de entrada
SESSIONID
Identificador de seo
TERMINAL
Identificador do terminal do usurio
LANGUAGE
Linguagem em uso
Exemplo:
SELECT USERENV( TERMINAL )
FROM Dual ;
/* Resultado: WINDOWS95 PC */

5
4

pg: 55

Programao de SGBD

VARIANCE( [ DISTINCT | ALL ] <expN> )


Retorna a variao de expN. Os valores nulos so ignorados.
Exemplo:
SELECT VARIANCE( VrSalario )
FROM Funcionario ;
/* Resultado: 309027.78 */

VSIZE( <exp> )
Retorna o nmero de bytes usados para armazenar internamente exp.
Exemplo:
SELECT NmFunc, VSIZE( NmFunc )
FROM Funcionario
WHERE NrMatric = 1001;
/* Resultado: 12 */

Converso de tipo de dados


Para
De
Caracter
Nmero
Data

Caracter

Nmero

Data

TO_CHAR
TO_CHAR

TO_NUMBER
ERRO

TO_DATE
TO_DATE
-

5
5

pg: 56

Programao de SGBD

Exerccios Prticos
Lista Nmero 1
Tpico: PL/SQL - Procedures
1) Escreva uma Stored Procedure que atualize a tabela Curso, substituindo uma descrio
existente por outra. Utilizar parametros para indicar a descrio antiga e a descrio nova.
Exemplo: Execute MudaDesc( 'Ingls' , 'B. Dados' );
Obs: a tabela curso deve conter os campos codigo_curso e descr_curso.
2) Considere o modelo E-R Paciente-Consulta j utilizado em aulas anteriores.
Escreva uma procedure que aceite o cdigo do Paciente como parmetro e:
- Calcule o Valor Total de suas consultas nos ltimos 3 meses
Se o valor for maior que 500,00
Gravar 'S' no campo Desconto da Tabela de Paciente
Caso contrrio
Gravar 'N' no campo Desconto da Tabela de Paciente.
- Utilizar o comando exception p/a capturar erros.
3) Faa o exerccio 2 que se encontra na pg 8 desta apostila.
4) Escreva uma procedure que valide senhas a partir de uma tabela de senhas.
Considere esta tabela com os campos:
Username varchar2(8)
Senha
varchar2(8).
A procedure ValidaSenha recebe como parmetro um username e uma password
e verifica se a password informada como parmetro igual a senha existente na tabela.
Se diferente gravar mensagem '#Password Invlida' em uma tabela tlog.
Se igual gravar #Password Vlida em uma tabela tlog.
Obs: Fazer o tratamento de exceo se houver erro na clusula select.
5) Realize o exerccio abaixo com base no modelo Paciente Consulta Mdico.
Criar um novo campo na tabela de mdico para conter o valor cobrado por consulta.
( sugesto: Chame este campo de VrHonor).
Atualize este campo com valores significativos, isto no deixe valores nulos.
Escreva uma procedure que grave um novo registro na tabela de consulta. Esta
procedure deve receber como parmetros os campos: codPaciente, codMedico e
Tipoconsulta. O valor da consulta deve ser calculado conforme algortmo abaixo.

5
6

pg: 57
D

Programao de SGBD
Se consulta do tipo Convnio (coluna TipoCon = C)
ento valorConsulta = VrHonor * 0.8
Seno, se paciente tem desconto ( coluna desconto = S)
Ento valorConsulta = VrHonor * 0.7
Seno valorConsulta = VrHonor ( cobrar preo normal)

5
7

pg: 58

Programao de SGBD

Lista Nmero 2
Tpico: PL/SQL Triggers
1- Sobre o modelo Paciente-Consulta, escreva um trigger que ao incluir uma consulta
verifique:
Se tipo = `C (convnio) gravar em uma tabela de guias a mensagem
"Emitir guia de convnio do paciente " <cod. Do paciente"> "-" <nome-do-paciente>.
A tabela de guias deve conter o campo Mensagem varchar2(70).
2- Escreva um trigger que ao se excluir uma consulta, grave uma linha na tabela Tlog.
A tabela Tlog deve conter :
data do sistema,
usurio que est efetuando a excluso (user),
cdigo da consulta excluda.
3- Sobre o modelo do Item-pedido, escreva um trigger que ao inserir um item do pedido
verifique se o cliente j possui mais de 10 pedidos com entrega no ms atual. Se sim,
aplicar um desconto de 15% ao preo do item que esta sendo cadastrado.
4- Crie um trigger que ao ser alterado o campo endereo da tabela de cliente, faa a
insero de uma linha na tabela de log com a mensagem "Observar mudana de
endereo" <codigo do cliente> <endereo velho><endereo novo>
Tablog (datalog,campo1,campo2).

5
8