Anda di halaman 1dari 42

Linguagens hospedeiras

Aplicações
 interrogar a BD
 tomar decisões
 dialogar com o utilizador
 etc.
linguagem de programação convencional
C, Cobol, Ada, Java

linguagem de manipulação de dados


optimizada para acesso rápido a grandes BD

O SGBD fornece um conjunto de procedimentos


que implementam as principais funções da LMD
PL/SQL - 1
Acesso à BD
ligação directa (API)
ODBC
JDBC
dados locais BD

aplicação

chamadas
LMD

PL/SQL - 2
Comunicação

 os programas de aplicação não escrevem


directamente na BD
 usam operações do nível conceptual - a bem da
independência dos dados
 se uma chamada da LMD produz uma relação
 esta pode ser maior que a área de dados local
 as linguagens convencionais são record-oriented
 logo
 é transferido para a área local um tuplo de cada vez
 o seguinte é obtido com uma instrução de fetch
 os dados na área local são variáveis normais do programa

PL/SQL - 3
PL/SQL - Ambiente
Motor PL/SQL
PL/SQL Execução da
PL/SQL PL/SQL
expressão
Block Block SQL
procedimental

Execução da expressão SQL

Servidor Oracle

PL/SQL - 4
PL/SQL - Benefícios

 Pode ser usado para agrupar várias perguntas SQL


num só bloco e enviá-lo de uma só vez para o
servidor.
 PL/SQL pode cooperar com as ferramentas de
desenvolvimento de aplicações Oracle tais como
Developer Forms e Reports adicionando poder de
processamento procedimental a estas ferramentas.
 Podemos tirar vantagens das capacidades
procedimentais do PL/SQL que não estão
presentes no SQL.

PL/SQL - 5
PL/SQL - Benefícios

 Os programas podem ser transportados para


qualquer ambiente (SO ou plataforma) que suporte
o servidor Oracle e PL/SQL, ou seja, os programas
PL/SQL podem correr em qualquer sítio onde o
servidor Oracle corra.
 Pode-se escrever programas e criar bibliotecas que
podem ser reutilizadas em diferentes ambientes.
 Pode-se declarar variáveis dinamicamente
baseadas em estruturas de dados ou tabelas e
colunas da BD (%TYPE, %ROWTYPE)

PL/SQL - 6
PL/SQL - Benefícios

 Desenvolvimento modular de
Declare programas.
ooo
Begin  Permite executar instruções
ooo condicionais.
Exception  Permite executar instruções num ciclo.
ooo  Permite processar várias linhas
End; devolvidas por uma pergunta através de
cursores.
 Os erros podem ser processados com
rotinas de tratamento de excepções.

PL/SQL - 7
Estruturas de controlo

 Instruções condicionais:
 IF-THEN-END IF
 IF-THEN-ELSE-END IF
 IF-THEN-ELSIF-END IF
 Ciclos
 LOOP
 FOR
 WHILE

PL/SQL - 8
Estruturas de controlo

LOOP
statement1;

EXIT [WHEN condition];
END LOOP;

condition - é uma variável booleana ou uma expressão


que evolui para (TRUE, FALSE ou NULL)

Exercício: bloco que insira 10 linhas numa tabela de


linhas de encomenda, para a encomenda 0017

PL/SQL - 9
Exemplo de ciclo

DECLARE
v_num_enc itens.no_enc%TYPE := 134;
Contador number(2) := 1;
BEGIN
LOOP
INSERT INTO itens( no_enc, linha )
values(v_num_enc, contador );
Contador:= contador+1;
Exit when contador >10;
End loop;
END;

PL/SQL - 10
Estruturas de controlo

FOR counter IN [REVERSE]


lower_bound . . uper_bound LOOP
statement1;
statement2;
...
END LOOP;

WHILE condition LOOP


statement1;
statement2;
...
END LOOP;

PL/SQL - 11
Frases SQL em PL/SQL

 Extrair uma única linha de dados da BD usando


SELECT;
 Alterar linhas da BD usando comandos DML;
 Controlar transacções com COMMIT,
ROLLBACK ou SAVEPOINTS;
 Determinar a saída gerada por DML com cursores;
 PL/SQL não suporta DDL (create/alter/drop table);
 PL/SQL não suporta DCL (Grant,…);

PL/SQL - 12
Estrutura

DECLARE - Optativo
Variáveis, cursores, excepções definidas pelo utilizador
BEGIN - Obrigatório
Expressões SQL Declare
Expressões PL/SQL
ooo
Begin
EXCEPTION - Optativo ooo
Acções a executar quando ocorrem erros Exception
END - Obrigatório ooo
End;

PL/SQL - 13
Tipos de Blocos

Anónimo Procedimento Função

[DECLARE] PROCEDURE name FUNCTION name


IS RETURN datatype
BEGIN IS
--statements BEGIN BEGIN
--statements -- statements
[EXCEPTION] RETURN value;
[EXCEPTION] [EXCEPTION]
END;
END; END;

•Um bloco dentro de outro funciona como uma instrução (composta)


•Nível de encaixe arbitrário
•Funções SQL disponíveis em PL/SQL excepto as de agregação

PL/SQL - 14
Procedimentos
Sintaxe:
CREATE [OR REPLACE] PROCEDURE procedure_name
(parameter1 [mode1] datatype1,
parameter2 [mode2] datatype2,
…)
IS | AS
PL/SQL Block
Exemplo: SQL> CREATE OR REPLACE PROCEDURE raise_salary
2 (v_id in emp.empno%TYPE)
3 IS
4 BEGIN
5 UPDATE emp
6 SET sal = sal * 1.1
7 WHERE empno = v_id;
8 END raise_salary;
9 /
Executar:
SQL> EXECUTE raise_salary (7369) PL/SQL> raise_salary(7369)

PL/SQL - 15
Funções
Sintaxe: CREATE [OR REPLACE] FUNCTION function_name
(parameter1 [mode1] datatype1,
parameter2 [mode2] datatype2,
…)
RETURN datatype
IS | AS
PL/SQL Block
Exemplo: SQL> CREATE OR REPLACE FUNCTION get_sal
2 (v_id IN emp.empno%TYPE)
3 RETURN NUMBER
4 IS v_salary emp.sal%TYPE :=0;
5 BEGIN
6 SELECT sal INTO v_salary
7 FROM emp WHERE empno = v_id;
8 RETURN (v_salary);
9 END get_sal;
10 /

PL/SQL - 16
Gatilhos

 Um gatilho é um bloco PL/SQL que executa


implicitamente sempre que um evento particular
acontece.
 Um gatilho pode ser da BD ou da aplicação.
 Quando executa?
 BEFORE - Antes de executar uma frase DML sobre uma
tabela.
 AFTER - Depois da frase DML
 INSTEAD OF - Executa o corpo do gatilho em vez da frase que
activou o gatilho.

PL/SQL - 17
Gatilhos

 Que frase DML activa gatilhos?


 INSERT; UPDATE; DELETE.
 Tipo de gatilhos: (quantas vezes deve o gatilho
executar ao acontecer o evento?)
 Statement - executa uma vez;
 Row - executa uma vez para cada linha afectada pelo gatilho.
 Corpo do gatilho
 Bloco PL/SQL ou chamada a procedimento.

PL/SQL - 18
Gatilhos
Sintaxe
CREATE [OR REPLACE] TRIGGER trigger_name
timing
event1 [OR event2 OR event3]
ON table_name
trigger_body
Ou (gatilho de linha)
CREATE [OR REPLACE] TRIGGER trigger_name
timing
event1 [OR event2 OR event3]
ON table_name
[REFERENCING OLD AS old / NEW AS new]
FOR EACH ROW
[WHEN condition]
trigger_body
PL/SQL - 19
Gatilhos
Exemplo
SQL> CREATE OR REPLACE TRIGGER derive_commission_pct
2 BEFORE INSERT OR UPDATE OF sal ON emp
3 FOR EACH ROW
4 BEGIN
5 IF NOT (:NEW.JOB IN (‘MANAGER’,’PRESIDENT’))
6 and :NEW.SAL > 5000
7 THEN
8 RAISE_APPLICATION_ERROR
9 (-20202,’Employee cannot earn this amount’);
10 END IF;
11 END;

•UPDATE EMP SET SAL=6500 WHERE ENAME=‘MILLER’;

PL/SQL - 20
Tipos de variáveis

 PL/SQL variáveis:
 Escalar (valor único);
 Composta (records);
 Referência (apontador);
 LOB (especificam a localização de objectos grandes. Ex:
imagens)
 Variáveis não PL/SQL: “bind or host variables”
 Usadas para passar valores obtidos durante a execução de
PL/SQL para o ambiente SQL*Plus

PL/SQL - 21
Variáveis ligadas
Variáveis definidas no PL/SQL não são visíveis pelo SQL*Plus
Bind variables -> Variáveis ligadas são variáveis que são criadas
no SQL*Plus e podem ser referidas no PL/SQL.
•Como criar
Ex: VARIABLE ret_val NUMBER;
•Para referir vars ligadas no PL/SQL usa-se (:) imediatamente
antes da variável
Ex: :ret_val :=1;
•Para mudar o valor desta variável no SQL*Plus é necessário
escrever um bloco PL/SQL.
Ex: SQL> begin
2 :ret_val:=4;
3 end;
4 /

PL/SQL - 22
Exemplo em SQL/Plus
SQL> VARIABLE g_sal_mensal NUMBER
SQL> ACCEPT p_sal_anual PROMPT ‘Salário anual: ‘
SQL> DECLARE
SQL> v_sal NUMBER(9,2) := &p_sal_anual;
SQL> BEGIN
SQL> :g_sal_mensal := v_sal / 12;
SQL> END;
SQL> /
SQL> PRINT g_sal_mensal
SQL> /* ou: SET SERVEROUTPUT ON
SQL> DBMS_OUTPUT.PUT_LINE(‘Salário mensal de ‘ ||
TO_CHAR(v_sal));
SQL> */

PL/SQL - 23
Declaração e atribuição
Sintaxe:
identifier [CONSTANT] datatype [NOT NULL]
[:= | DEFAULT expr];

Exemplos:
Declare
v_hiredate DATE;
v_deptno NUMBER(2) NOT NULL :=10;
c_comm CONSTANT NUMBER :=1400;
v_ename emp.ename%TYPE;

Atribuição: Variáveis %TYPE herdam o


v_hiredate := ‘31-DEC-98’; tipo da coluna base e suportam
mudanças nessa definição

PL/SQL - 24
Tipos escalares

 Varchar2(max_comp)
 Number[(precisão,casas decimais)]
 Date ATENÇÃO: As variáveis
 Char [(max_comp)] não devem ter nomes
 Long iguais a nomes das
 Long Raw colunas da BD.
 Boolean Ambiguidade: não se
 true, false, null sabe se se escreve na BD
 Binary_integer ou na variável!
 Pls_integer
PL/SQL - 25
Exercício sobre variáveis

 Quais as declarações erradas?


DECLARE
v_id number(4);
v_x, v_y, v_z varchar2(10);
v_aniversario date not null;
v_em_stock boolean := 1;

PL/SQL - 26
Alcance das variáveis

 Qual o valor de cada variável em ambos os blocos?


DECLARE
V_sal number(7,2) := 60000;
V_com number(7,2) := v_sal*0.2;
V_mensagem varchar2(255) := ‘ de qualidade.’;
Begin ...
Declare
V_sal number(7,2) := 50000;
V_com number(7,2) := 0;
V_total number(7,2) := v_sal+v_com;
Begin ...
V_mensagem := ‘Operario’ || v_mensagem;
End;
V_mensagem := ‘Secretario ’ || v_mensagem;
END;

PL/SQL - 27
PL/SQL - SELECT em PL/SQL
SINTAXE: SELECT select_list
INTO {variable_name[, variable_name]…
| record_name}
FROM table
WHERE condition;

Exemplo: DECLARE
v_sum_sal emp.sal%TYPE;
v_deptno NUMBER NOT NULL :=10;
• erro se pergunta devolver BEGIN
0 (NO_DATA_FOUND) ou SELECT SUM(sal) --group function
mais do que 1 linha INTO v_num_sal
(TOO_MANY_ROWS) FROM emp
• cláusula INTO crucial WHERE dptno=v_deptno;
END;

PL/SQL - 28
PL/SQL - INSERT/UPDATE em PL/SQL

BEGIN
INSERT INTO emp(empno, ename, job, deptno)
VALUES empno_sequence.nextval,’Harding’,’Clerk’, 10);
END;

DECLARE
v_sal_increase emp.sal%TYPE := 2000;
BEGIN
UPDATE emp
SET sal:= sal + v_sal_increase
WHERE job = ‘ANALYST’;
END;

PL/SQL - 29
Registos

 Definir um tipo RECORD para agrupar dados


heterogéneos
 TYPE nome_tipo IS RECORD (campo[, campo]...);
 nome_campo tipo [[NOT NULL] {:= | DEFAULT} expressão]

 Pode-se herdar a definição de um registo


DECLARE
registo_emp emp%ROWTYPE
BEGIN
SELECT * INTO registo_emp FROM emp WHERE...
 Tornando desnecessário conhecer em detalhe a tabela base

PL/SQL - 30
Registos encaixados
 DECLARE
TYPE TimeRec IS RECORD (mins SMALLINT, hrs SMALLINT);
TYPE MeetingRec IS RECORD (
day DATE,
time_of TimeRec, -- nested record
room_no INTEGER(4));
TYPE PartyRec IS RECORD (
day DATE,
time_of TimeRec, -- nested record
place VARCHAR2(25));
seminar MeetingRec;
party PartyRec;
BEGIN ...
party.time_of := seminar.time_of;
END;

PL/SQL - 31
Tabelas

 Coluna de Binary integer funciona como índice; segunda


coluna (de conteúdo) pode ser simples ou composta
DECLARE
TYPE CourseList IS TABLE OF VARCHAR2(10);
courses CourseList;
BEGIN
courses := CourseList('Biol 4412', 'Psyc 3112', 'Anth 3001');
courses.DELETE(3); -- delete element 3
/* PL/SQL keeps a placeholder for element 3. So, the
next statement appends element 4, not element 3. */
courses.EXTEND; -- append one null element
/* Now element 4 exists, so the next statement does
not raise SUBSCRIPT_BEYOND_COUNT. */
courses(4) := 'Engl 2005';

PL/SQL - 32
Tabelas
DECLARE
TYPE NumList IS TABLE OF NUMBER;
depts NumList := NumList(10, 20, 30, 40);
BEGIN
depts.DELETE(3); -- apaga terceiro elemento
FORALL i IN depts.FIRST..depts.LAST – ligação em massa
DELETE FROM emp WHERE deptno = depts(i); -- causa erro
END;

 Métodos para tabelas


 Exists First Prior Extend Delete
 Count Last Next Trim

PL/SQL - 33
PL/SQL - Cursores

 Um cursor é uma área privada do SQL.


 Há dois tipos de cursores:
 Implícitos (chamados SQL)
 Explícitos
 O servidor Oracle usa cursores implícitos para
analisar e executar código SQL.
 Os cursores explícitos são explicitamente
declarados pelo programador.

PL/SQL - 34
Atributos do cursor SQL

 Através dos atributos do cursor implícito


(chamado SQL) podemos testar a saída produzida
por uma pergunta SQL:
 SQL%ROWCOUNT - nº de linhas afectadas pela mais recente
frase SQL;
 SQL%FOUND - TRUE se a mais recente frase SQL afecta uma
ou mais linhas;
 SQL%NOTFOUND - TRUE se a mais recente frase SQL não
afecta nenhuma linha;
 SQL%ISOPEN - Sempre FALSE porque o PL/SQL fecha
sempre os cursores implícitos depois de os executar;

PL/SQL - 35
Controlo de cursores explícitos

no

Declare Open Fetch Empty? Close


yes
cria uma identifica carrega linha
testa fim de liberta conjunto
área no SQL conjunto corrente
dados activo
activo

PL/SQL - 36
Cursores - declaração

CURSOR cursor_name [(parameter[, parameter]...)]


[RETURN return_type] IS select_statement;
 cursor_parameter_name [IN] datatype [{:= | DEFAULT}
expression]

DECLARE
CURSOR c1 IS SELECT empno, ename, job, sal FROM emp
WHERE sal > 2000;
CURSOR c2 RETURN dept%ROWTYPE IS
SELECT * FROM dept WHERE deptno = 10;
 sem cláusula INTO

PL/SQL - 37
Cursor num Package

CREATE PACKAGE BODY emp_stuff AS


CURSOR c1 RETURN emp%ROWTYPE IS
SELECT * FROM emp WHERE deptno = 20; --
new WHERE clause
...
END emp_stuff;

PL/SQL - 38
Processamento das linhas
DECLARE
emp_rec emp%ROWTYPE;
-- ou emp_rec emp_stuff.c1%ROWTYPE
...
BEGIN
...
OPEN emp_stuff.c1;
LOOP
FETCH emp_stuff.c1 INTO emp_rec;
EXIT WHEN emp_suff.c1%NOTFOUND;
...
END LOOP;
CLOSE emp_stuff.c1;
END;
PL/SQL - 39
Atributos dos cursores explícitos

 Através dos atributos dos cursores explícitos


podemos controlar o processamento do resultado:
 SQL%ROWCOUNT - nº de linhas devolvidas até ao momento;
 SQL%FOUND - TRUE se o fetch mais recente devolveu linha;
 SQL%NOTFOUND - TRUE se o fetch mais recente não
devolveu linha;
 SQL%ISOPEN – TRUE se o cursor estiver aberto
 Convém fechar o cursor; máximo de cursores
abertos (50) no parâmetro da BD
OPEN_CURSORS

PL/SQL - 40
Cursor de ciclo FOR
DECLARE
result temp.col1%TYPE;
CURSOR c1 IS
SELECT n1, n2, n3 FROM data_table WHERE exper_num = 1;
BEGIN
FOR c1_rec IN c1 LOOP
/* calcula e armazena os resultados */
result := c1_rec.n2 / (c1_rec.n1 + c1_rec.n3);
INSERT INTO temp VALUES (result, NULL, NULL);
END LOOP;
COMMIT;
END;

PL/SQL - 41
Cursor de sub-pergunta
DECLARE
bonus REAL;
BEGIN
FOR emp_rec IN (SELECT empno, sal, comm FROM emp) LOOP
bonus := (emp_rec.sal * 0.05) + (emp_rec.comm * 0.25);
INSERT INTO bonuses VALUES (emp_rec.empno, bonus);
END LOOP;
COMMIT;
END;

 Neste caso não se pode usar os atributos de cursor porque o


cursor não tem nome

PL/SQL - 42

Anda mungkin juga menyukai