You are on page 1of 128

LINGUAGEM PL/SQL

Kellyton Campos Feitosa

kellyton@gmail.com

Procedural Language/SQL - PL/SQL


PL / SQL uma extenso do SQL com as caractersticas de linguagens de programao. Manipulao de dados e de consulta, instrues SQL esto includas dentro das unidades procedurais do cdigo. A PL/SQL combina o poder e flexibilidade da SQL com as construes procedurais de uma linguagem de 3 gerao. Programas PL/SQL podem ser executados em todas as plataformas do ambiente Oracle Database.

Kellyton Campos Feitosa

kellyton@gmail.com

Melhor Desempenho
PL / SQL pode melhorar o desempenho de um aplicativo, dependendo do ambiente de execuo. PL / SQL pode ser usado para agrupar as instrues SQL dentro de um nico bloco e enviar todo o bloco para o servidor em uma nica chamada, reduzindo assim o trfego de rede. Sem PL / SQL: As instrues SQL so processados um de cada vez. Cada declarao SQL resultados em outra chamada para o servidor Oracle e a sobrecarga de alto desempenho. Em um ambiente de rede, a sobrecarga pode se tornar significativo
Kellyton Campos Feitosa

kellyton@gmail.com

Melhor Desempenho
SQL

Aplicao Aplicao

SQL SQL SQL

Sem Sem PL/SQL PL/SQL

Aplicao Aplicao

SQL IF...THEN SQL ELSE SQL END IF; SQL

Com Com PL/SQL PL/SQL

Kellyton Campos Feitosa

kellyton@gmail.com

Estrutura do bloco PL/SQL


DECLARE (opcional) /* Seo declarativa variveis, tipos, cursores e subprogramas locais */ BEGIN (obrigatrio) /* Seo executvel - instrues SQL e procedurais entram aqui. Essa a principal sesso do bloco PL/SQL, e a nica obrigatria. */ EXCEPTION (opcional) /* Seo de tratamento de excees instrues de tratamento de erros entram aqui. */ END; (obrigatrio)

Kellyton Campos Feitosa

kellyton@gmail.com

Estrutura do bloco PL/SQL



DECLARE DECLARE Opcional Opcional Variables, Variables, cursors, cursors, user-defined user-defined exceptions exceptions BEGIN BEGIN Obrigatrio Obrigatrio SQL SQL statements statements PL/SQL PL/SQL statements statements EXCEPTION EXCEPTION Opcional Opcional Actions Actions to to perform perform when when errors errors occur occur

END; END; Obrigatrio Obrigatrio

Kellyton Campos Feitosa

kellyton@gmail.com

Estrutura do bloco PL/SQL


DECLARE DECLARE v_variable v_variable VARCHAR2(5); VARCHAR2(5); BEGIN BEGIN SELECT SELECT column_name column_name INTO INTO v_variable v_variable FROM FROM table_name; table_name; EXCEPTION EXCEPTION WHEN WHEN exception_name exception_name THEN THEN ... ... END; END;

DECLARE BEGIN EXCEPTION END;

Kellyton Campos Feitosa

kellyton@gmail.com

Tipos de blocos PL/SQL


Blocos annimos: construdos dinamicamente e executados apenas uma vez. Subprogramas: consistem em procedures e funes. Triggers: consistem em um bloco PL/SQL que est associado a um evento (automtico) que ocorre no banco de dados.

Kellyton Campos Feitosa

kellyton@gmail.com

Tipos de blocos PL/SQL


Annimos
[DECLARE] [DECLARE] BEGIN BEGIN --statements --statements [EXCEPTION] [EXCEPTION] END; END;

Procedures
PROCEDURE PROCEDURE name name IS IS BEGIN BEGIN --statements --statements [EXCEPTION] [EXCEPTION] END; END;

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

Kellyton Campos Feitosa

kellyton@gmail.com

Identificadores
Os identificadores so usados para nomear objetos da PL/SQL como variveis, cursores, subprogramas, etc. Consistem em uma letra, opcionalmente seguida por qualquer seqncia de caracteres incluindo nmeros e ($), (#) e (_). Devem possuir comprimento mximo de 30 caracteres No h distino entre letras maiscula e minscula No pode possuir nome igual uma palavra reservada, ex: BEGIN, END Podem ser identificados com aspas para possurem espaos e distino entre letras maisculas e minsculas. EX: X / Y, variavel A.
Kellyton Campos Feitosa

10

kellyton@gmail.com

Comentrios
Melhoram a legibilidade e tornam os programas mais compreensveis. -- Comentrio de linha /* */ comentrio de bloco Ex.: Comentrios de uma nica linha, atravs de dois traos --":
v_data := SYSDATE; --varivel recebe data atual

Comentrios de mltiplas linha, usando /* para inicar e */ para fechar:


BEGIN /* Estamos agora dentro de um comentrio. Aqui a continuao do comentrio. */ NULL; END;

Kellyton Campos Feitosa

11

kellyton@gmail.com

Declarao de varivel
Nome_da_varivel [CONSTANT] datatype [NOT NULL] [{:= | DEFAULT} valor];

DECLARE v_dataInicial DATE; v_contador BINARY_INTEGER NOT NULL := 0; v_nome VARCHAR2(20); c_PI CONSTANT NUMBER DEFAULT 3.14;

Kellyton Campos Feitosa

12

kellyton@gmail.com

Tipos de Dados no PL/SQL


So divididos nas seguintes categorias: CHARACTER NUMBER DATE LOB BOOLEANOS, somente pl/sql TIPOS COMPOSTOS TIPOS DE OBJETO TIPOS DE REFERNCIA

Kellyton Campos Feitosa

13

kellyton@gmail.com

Tipos Character
Usados para armazenar dados alfanumricos. CHAR(<n>) armazena string de tamanho fixo. Tamanho default 1, mximo 32.767. Subtipo: CHARACTER VARCHAR2(<n>) armazena string de tamanho varivel. possvel armazenar string de at 32.767 bytes. Subtipo: STRING VARCHAR(<n>) sinnimo para o tipo VARCHAR2. NCHAR(<n>) e NVARCHAR2(<n>) possuem as mesmas caractersticas dos tipos CHAR e VARCHAR2 e so usados para armazenar dados NLS (National Language Support). A arquitetura Oracle NLS permite armazenar, processar e recuperar informaes em linguagens nativas. LONG um tipo de dados que se tornou obsoleto com a chegada dos tipos LOB (Large Object). O tipo LONG armazena strings de tamanho varivel de no mximo 2 GB.
Kellyton Campos Feitosa

14

kellyton@gmail.com

Tipos Numeric
Usado para armazenar dados numricos com preciso de at 38 digitos. NUMBER(<x>, <y>) onde <X> corresponde ao nmero de dgitos e <Y> o nmero de casas decimais. Valores inseridos em colunas numricas com nmero de casas decimais menor que o dado inserido sero arredondados. Subtipos: DEC, DECIMAL, DOUBLE PRECISION, FLOAT, INTEGER, INT, NUMERIC, REAL, SMALLINT. BINARY_INTEGER utilizado para armazenar inteiros com sinal, que variam de 2147483647 a 2147483647. Requerem menos memria que tipos NUMBER. Subtipos: NATURAL (n>=0), NATURALN (n>=0 not null), POSITIVE (n>0), POSITIVEN (n>0 not null), SIGNTYPE (-1, 0, 1). PLS_INTEGER Possui as mesmas caractersticas do tipo BINARY_INTEGER, entretanto possui melhor performance para clculos.
Kellyton Campos Feitosa

15

kellyton@gmail.com

Tipos Date
O tipo DATE permite valores de data e hora. O formato padro definido pelo parmetro NLS_DATE_FORMAT. O Oracle armazena internamente a data em formato de nmero juliano com a parte fracionria usada para controlar a hora. Uma data Juliana corresponde ao nmero de dias desde 1 de Janeiro de 4712 A.C. Para operaes aritmticas com datas no Oracle, basta adicionar ou subtrair nmeros inteiros ou fracionrios. Por exemplo, SYSDATE + 1 para somar uma dia, 1/24 para acrescentar uma hora, 1/(24x60) ou 1/1440 para acrescentar 1 minuto e 1/(24x60x60) ou 1/86400 para um segundo.

Kellyton Campos Feitosa

16

kellyton@gmail.com

Tipos Date

TIMESTAMP semelhante ao tipo DATE, com a diferena de armazenar frao de segundos com preciso de at 9 digitos. TIMESTAMP WITH TIME ZONE armazena data/hora com informaes de fuso horrio. TIMESTAMP WITH LOCAL TIME ZONE armazena data/hora no fuso horrio do servidor. Quando o usurio seleciona os dados, o valor ajustado para as configuraes da sua sesso. INTERVAL YEAR TO MONTH usado para armazenar espao de tempo em anos e meses. INTERVAL DAY TO SECOND permite especificar intervalos em dias, horas, minutos e segundos.

Kellyton Campos Feitosa

17

kellyton@gmail.com

Tipos LOB
Large Object (LOB) datatypes so usado para armazenar dados no estruturados como imagens, arquivos binrios. Os tipos LOBs podem armazenar at 4GB * (tamanho bloco) de informao. A manipulao dos tipos LOB feita atravs da package DBMS_LOB. BLOB - Binary Large Object, armazena at 4GB*(tamanho bloco) de dados binrios no banco. CLOB - Character Large Object Armazena at 4GB*tamanho_bloco de dados textuais. BFILE - Binary File, armazena at 8 terabytes de dados em arquivos binrios externos. Uma coluna BFILE armazena um ponteiro para o arquivo armazenado no sistema operacional.
Kellyton Campos Feitosa

18

kellyton@gmail.com

Tipo booleano
O nico tipo de dados na famlia booleana o BOOLEAN. Podem conter apenas os valores TRUE, FALSE ou NULL.

Kellyton Campos Feitosa

19

kellyton@gmail.com

Expresses booleanas
Uma expresso booleana qualquer expresso que avaliada como um valor booleano. Somentes os valores TRUE, FALSE e NULL podem ser atribudos a uma varivel booleana. As variveis so conectados por operadores lgicos AND, OR e NOT.

Kellyton Campos Feitosa

20

kellyton@gmail.com

Tabela verdade
NOT TRUE FALSE FALSE TRUE NULL NULL

AND TRUE FALSE NULL

TRUE TRUE FALSE NULL

FALSE FALSE FALSE FALSE

NULL NULL FALSE NULL

OR TRUE FALSE NULL

TRUE TRUE TRUE TRUE

FALSE TRUE FALSE NULL

NULL TRUE NULL NULL

Kellyton Campos Feitosa

21

kellyton@gmail.com

Tipos Compostos
Os tipos compostos disponveis em PL/SQL so registros, tabelas e varrays. Um tipo composto um que tem componentes dentro dele. Uma varivel do tipo composta contm uma ou mais variveis.

Kellyton Campos Feitosa

22

kellyton@gmail.com

Tipos de referencia
Um tipo de referncia na PL/SQL semelhante a um ponteiro em C. Em PL/SQL usamos os tipos REF, REF CURSOR e SYS_REFCURSOR.

Kellyton Campos Feitosa

23

kellyton@gmail.com

Tipos de objeto
Consiste em um tipo composto que possui atributos (variveis de outros tipos) e mtodos (subprogramas) dentro dele.

Kellyton Campos Feitosa

24

kellyton@gmail.com

Utilizando %TYPE
Utilizado para declarar uma varivel com o mesmo tipo de uma coluna de alguma tabela, ex:
DECLARE v_Nome STUDENTS.FIRST_NAME%TYPE; v_Idade PLS_INTEGER NOT NULL :=0; v_IdadeTemp v_Idade%TYPE; --no herda restrio nem valor default

Kellyton Campos Feitosa

25

kellyton@gmail.com

Funes para Converso Explcita de tipos dados

Kellyton Campos Feitosa

26

kellyton@gmail.com

Operadores
O operador mais bsico na PL/SQL o de atribuio. A sintaxe :
Varivel := valor;

Kellyton Campos Feitosa

27

kellyton@gmail.com

Operadores

Operador **, NOT *,/ +,-,|| =,!=,<,>,<=,>=, IS NULL, LIKE, BETWEEN, IN AND OR Binrio Binrio Binrio

Tipo

Descrio Exponenciao, negao lgica Multiplicao, diviso Adio, subtrao, concatenao Comparao lgica

Binrio (exceto IS NULL que unrio) Binrio Binrio

Conjuno lgica Incluso lgica

Kellyton Campos Feitosa

28

kellyton@gmail.com

Estruturas de controle PL/SQL


Permitem controlar o comportamento do bloco medida que ele est sendo executado. IF-THEN- ELSE CASE Loops while Loops FOR numricos

Kellyton Campos Feitosa

29

kellyton@gmail.com

IF-THEN- ELSE

IF v_NumberSeats < 50 THEN v_Comment := 'Fairly small'; ELSIF v_NumberSeats < 100 THEN v_Comment := 'A little bigger'; ELSE v_Comment := 'Lots of room'; END IF; ....

Kellyton Campos Feitosa

30

kellyton@gmail.com

CASE I
CASE v_Major WHEN 'Computer Science' THEN v_CourseName := 'CS 101'; WHEN 'Economics' THEN v_CourseName :='ECN 203'; WHEN 'History' THEN v_CourseName := 'HIS 101'; WHEN 'Music' THEN v_CourseName := 'MUS 100'; WHEN 'Nutrition' THEN v_CourseName := 'NUT 307'; ELSE v_CourseName := 'Unknown'; END CASE;
* Quando uma condio no for validada por uma condio CASE, a PL/SQL interromper a execuo com o erro CASE_NOT_FOUND, ou ORA-6592:

Kellyton Campos Feitosa

31

kellyton@gmail.com

CASE II

CASE WHEN WHEN ... WHEN [ELSE END;

search_condition1 THEN result1 search_condition2 THEN result2 search_conditionN THEN resultN resultN+1]

* Quando uma condio no for validada por uma condio CASE, a PL/SQL interromper a execuo com o erro CASE_NOT_FOUND, ou ORA-6592:

Kellyton Campos Feitosa

32

kellyton@gmail.com

Loops while
A condio avaliada antes de cada iterao do loop. Sintaxe:
WHILE condio LOOP Seqncia_de_instrues; END LOOP; ... WHILE v_Counter <= 50 LOOP INSERT INTO temp_table VALUES (v_Counter, 'Loop index'); v_Counter := v_Counter + 1; END LOOP; ...

Se desejado, as instrues EXIT ou EXIT WHEN podem ainda ser utilizadas dentro de um loop WHILE para sair prematuramente do loop.
Kellyton Campos Feitosa

33

kellyton@gmail.com

Loops FOR numricos


Loop que possui um nmero definido de iteraes. Sintaxe:
FOR contador IN [REVERSE] limite_inferior..limite_superior LOOP Seqncia_de_instrues; END LOOP;

Exemplo:
BEGIN --no necessrio declarer a varivel v_counter --ela ser automaticamente declarada como BINARY_INTERGER FOR v_Counter IN 1..50 LOOP INSERT INTO temp_table VALUES (v_Counter, 'Loop Index'); END LOOP; END;

Se desejado, as instrues EXIT ou EXIT WHEN podem ainda ser utilizadas dentro de um loop FOR para sair prematuramente do loop.

Kellyton Campos Feitosa

34

kellyton@gmail.com

Loops FOR numricos


Se a palavra REVERSE estiver presente no loop FOR, o ndice de loop ir iterar a partir do valor alto para o valor baixo. Exemplo:
DECLARE v_Baixo NUMBER := 10; v_Alto NUMBER := 40; BEGIN FOR v_Counter in REVERSE v_Baixo .. v_Alto LOOP INSERT INTO temp_table VALUES(v_Counter, Teste); END LOOP; END;b

Kellyton Campos Feitosa

35

kellyton@gmail.com

dbms_output.put_line
Package que vem com o Oracle e que permite escrever mensagens. til para fazer debug em ambientes sem recursos de depurao.
Set serveroutput on begin dbms_output.put_line('Ol a todos!'); end;

Kellyton Campos Feitosa

36

kellyton@gmail.com

Parte II

Kellyton Campos Feitosa

37

kellyton@gmail.com

Registros PL/SQL
Os registros PL/SQL so semelhantes a estruturas C. Um registro fornece uma maneira de lidar com variveis separadas, mas relacionadas como uma unidade. Sintaxe:
TYPE nome_tipo IS RECORD( campo1 tipo1 [NOT NULL] [:= valor], campo2 tipo2 [NOT NULL] [:= valor], ...);

Kellyton Campos Feitosa

38

kellyton@gmail.com

Registros PL/SQL
DECLARE TYPE t_Rec1Type IS RECORD ( Field1 NUMBER, Field2 VARCHAR2(5)); TYPE t_Rec2Type IS RECORD ( Field1 NUMBER, Field2 VARCHAR2(5)); v_Rec1 t_Rec1Type; v_Rec2 t_Rec2Type; v_Rec3 t_Rec1Type; v_Rec4 t_Rec1Type; BEGIN /*Apesar de possurem a mesma estrutura, a atribuio abaixo no permitida */ v_Rec1 := v_Rec2; --A forma correta seria: v_Rec1.Field1 := v_Rec2.Field1; v_Rec2.Field2 := v_Rec2.Field2; /*Essa atribuio permitida pois ambas variveis so do mesmo tipo */ v_Rec3 := v_Rec4; END;

Kellyton Campos Feitosa

39

kellyton@gmail.com

Registros PL/SQL
DECLARE TYPE t_StudentRecord IS RECORD ( FirstName students.first_name%TYPE, LastName students.last_name%TYPE, Major students.major%TYPE); v_Student t_StudentRecord; BEGIN SELECT first_name, last_name, major INTO v_Student FROM students WHERE ID = 10000; END;

Kellyton Campos Feitosa

40

kellyton@gmail.com

Utilizando %ROWTYPE
Declarar um tipo com base na definio de tabela ou cursor. Exemplo:
DECLARE v_Student students%ROWTYPE; BEGIN SELECT first_name, last_name, major INTO v_Student FROM students WHERE ID = 10000; END;

Kellyton Campos Feitosa

41

kellyton@gmail.com

SQL DENTRO DA LINGUAGEM PL/SQL

As nicas instrues SQL permitidas diretamente em um programa PL/SQL so: DMLs (SELECT, INSERT, UPDATE, DELETE, MERGE) Instrues de controle de transao (COMMIT, ROLLBACK, SAVEPOINT...).

Kellyton Campos Feitosa

42

kellyton@gmail.com

Declarao Select
Recupera os dados do banco de dados para as variveis PL/SQL.
DECLARE v_StudentRecord students%ROWTYPE; v_Department classes.department%TYPE; v_Course classes.course%TYPE; BEGIN SELECT * INTO v_StudentRecord FROM students WHERE id = 10000; SELECT department, course INTO v_Department, v_Course FROM classes WHERE room_id = 20003; END;

Kellyton Campos Feitosa

43

kellyton@gmail.com

A clusula RETURNING
Utilizada para obter as informaes sobre a linha ou linhas que acabaram de ser processadas por um comando DML, como por exemplo conhecer a ROWID da linha que acabou de ser includa sem a necessidade de submeter um comando SELECT para o banco de dados. Vantagens: - fewer network round trips (Aplicaes tagarelas) - less server CPU time - fewer cursors - less server memory are required.
Kellyton Campos Feitosa

44

kellyton@gmail.com

A clusula RETURNING
declare name VARCHAR2(15); new_sal NUMBER; emp_id NUMBER := 100; BEGIN UPDATE emp SET sal = sal * 1.1 WHERE empno = emp_id RETURNING ename, sal INTO name, new_sal; -- Now do computations involving name and new_sal END;

Kellyton Campos Feitosa

45

kellyton@gmail.com

Controle de transaes
Uma transao uma srie de instrues SQL que podem ser aplicadas com sucesso, falhas ou canceladas. Os comandos para controlar transaes so:
Script: Parte ll - Controle Transacional.sql

COMMIT [WORK] para confirmar uma transao ROLLBACK [WORK] [TO [SAVEPOINT] nome_do_savepoint] para cancelar parte ou toda uma transao SAVEPOINT nome_do_savepoint para criar um ponto de salvamento na transao SET TRANSACTION para alterar o modo de consistncia de leitura de uma transao set transaction read only; deve ser a primeira instruo da transao No funciona com o usurio SYS

Para voltar ao normal, finalize a transao com commit ou rollback; Kellyton Campos Feitosa kellyton@gmail.com 46

TRATAMENTO DE ERROS
A PL/SQL implementa tratamento de erro por meio de excees e handlers de exceo. Tipos de erros PL/SQL
Tipos de erro Na compilao Em tempo de execuo Informado pelo Compilador PL/SQL Mecanismo de Execuo Como tratado Interativamente Programaticamente

Interativamente: o compilador informa os erros e voc tem de corrigilos. Programaticamente: as excees so levantadas e capturadas pelos blocos de exceo.

Kellyton Campos Feitosa

47

kellyton@gmail.com

TRATAMENTO DE ERROS
SET SERVEROUTPUT ON
DECLARE x NUMBER := 1; y NUMBER := 2; z NUMBER := 0; BEGIN y := 1 / z; z := x + y; EXCEPTION WHEN OTHERS THEN /* Handler para executar todos os erros */ --Handle_error(); dbms_output.put_line('Erro diviso zero'); END;

Kellyton Campos Feitosa

48

kellyton@gmail.com

Declarando Excees
As excees so declaradas na seo declarativa do bloco, levantadas na seo executvel e tratadas na seo de exceo. H dois tipos de excees : definidas pelo usurio predefinidas.

Kellyton Campos Feitosa

49

kellyton@gmail.com

Excees definidas pelo usurio


Exemplo:
DECLARE e_TooManyStudents EXCEPTION;

Kellyton Campos Feitosa

50

kellyton@gmail.com

Excees predefinidas
Erro do Oracle
ORA-0001 ORA-0051 ORA-0061 ORA-1001 ORA-1012 ORA-1017 ORA-1403 ORA-1410 ORA-1422 ORA-1476 ORA-1722 ...

Exceo Equivalente
DUP_VAL_ON_INDEX TIMEOUT_ON_RESOURCE TRANSACTION_BACKED_OUT INVALID CURSOR NOT_LOGGED_ON LOGIN_DENIED NO_DATA_FOUND SYS_INVALID_ROWID TOO_MANY_ROWS ZERO_DIVIDE INVALID_NUMBER

Descrio
Uma restrio nica violada. (PK/UK) O tempo limite ocorreu ao esperar pelo recurso. A transao foi revertida devido a um impasse. Operao ilegal de cursor. No conectado ao Oracle. Nome usurio/senha invalida. Nenhum dado localizado. Converso para um ROWID universal falhou. Uma instruo SELECT.INTO corresponde a mais de uma linha. Diviso por zero. Converso para um nmero falhou por exemplo. IA no e valido.

Kellyton Campos Feitosa

51

kellyton@gmail.com

Levantando excees
Quando o erro associado com uma exceo ocorrer, a exceo levantada. Excees definidas pelo usurio so levantadas explicitamente via instruo RAISE. Todas as excees podem ser capturadas com um handler OTHERS e deve ser utilizada como ltima alternativa.

Kellyton Campos Feitosa

52

kellyton@gmail.com

Levantando excees
DECLARE -- Exception to indicate an error condition e_TooManyStudents EXCEPTION; -- Current number of students registered for HIS-101 v_CurrentStudents NUMBER(3); -- Maximum number of students allowed in HIS-101 v_MaxStudents NUMBER(3); BEGIN /* Find the current number of registered students, and the maximum number of students allowed. */ SELECT current_students, max_students INTO v_CurrentStudents, v_MaxStudents FROM classes WHERE department = 'HIS' AND course = 101; /* Check the number of students in this class. */ IF v_CurrentStudents > v_MaxStudents THEN /* Too many students registered -- raise exception. */ RAISE e_TooManyStudents; END IF; END;

Kellyton Campos Feitosa

53

kellyton@gmail.com

Tratando excees

EXCEPTION

WHEN

e_TooManyStudents

OR

TOO_MANY_ROWS

THEN

Seqncia_de_instrues1; WHEN nome_exceo THEN Seqncia_de_instrues2; WHEN OTHERS THEN Seqncia_de_instrues3; END;

Kellyton Campos Feitosa

54

kellyton@gmail.com

SQLCODE e SQLERRM
SQLCODE retorna o cdigo do erro atual SQLERRM retorna o texto da mensagem do erro atual. Inclusive os erros em cascata se existirem. O tamanho mximo da mensagem de erro de 2048 bytes, incluindo o cdigo de erro, as mensagens aninhadas, e inseres de mensagens, tais como nomes de tabela e coluna.

Kellyton Campos Feitosa

55

kellyton@gmail.com

O pragma EXCEPTION_INIT
Voc pode associar uma exceo nomeada com um erro do Oracle em particular. Isso d a capacidade de interromper especificamente esse erro, sem ser via um handler OTHERS.
PRAGMA EXCEPTION_INI ( nome_da_exceo, numero_erro_do_Oracle);

Kellyton Campos Feitosa

56

kellyton@gmail.com

O pragma EXCEPTION_INIT
DECLARE e_MissingNull EXCEPTION; PRAGMA EXCEPTION_INIT(e_MissingNull, -1400); BEGIN INSERT INTO students (id) VALUES (NULL); EXCEPTION WHEN e_MissingNull then INSERT INTO log_table (info) VALUES ('ORA-1400 occurred'); END;

Kellyton Campos Feitosa

57

kellyton@gmail.com

RAISE_APPLICATION_ERROR
Voc pode utilizar a funo predefinida RAISE_APPLICATION_ERROR para criar suas prprias mensagens de erro.
RAISE_APPLICATION_ERROR ( numero_do_erro, mensagem_do_erro, [true | false]);

True -> A mensagem no sobrepe as mensagens anteriores False -> A mensagem sobrepe as mensagens anteriores Onde numero_do_erro um valor entre 20.000 e 20.999, mensagem_do_erro, o texto associado, com no mximo 2048 bytes.

Kellyton Campos Feitosa

58

kellyton@gmail.com

RAISE_APPLICATION_ERROR

Begin RAISE_APPLICATION_ERROR( -20000, 'O salrio no pode ser maior que o do presidente' ); End;

Kellyton Campos Feitosa

59

kellyton@gmail.com

DBMS_UTILITY.FORMAT_CALL_STACK
Um problema com as excees que quando ela ocorre, no h nenhuma maneira fcil para informar qual parte do cdigo estava sendo executado nesse momento, utilize a funo DBMS_UTILITY.FORMAT_CALL_STACK para retornar um trace, para se chegar ao ponto onde a exceo foi gerada.

Kellyton Campos Feitosa

60

kellyton@gmail.com

Parte III

Kellyton Campos Feitosa

61

kellyton@gmail.com

CURSORES
Cursores so trechos alocados de memria destinados a processar as declaraes SELECT. Podem ser: Cursores Implcitos, definidos pelo prprio PL/SQL Cursores Explcitos definidos manualmente.

Kellyton Campos Feitosa

62

kellyton@gmail.com

Cursores explcitos
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 (open) ; ler os dados produzidos pelo cursor (fetch) ; fechar (desalocar a memria) do cursor (close).

Kellyton Campos Feitosa

63

kellyton@gmail.com

Cursores Explcitos

Declarando CURSOR <nome do cursor> IS <declarao SELECT> ; Abrindo OPEN <nome-do-cursor>; Lendo FETCH <nome-do-cursor> INTO <lista de variveis> ; Fechando CLOSE <nome-do-cursor> ;

Kellyton Campos Feitosa

64

kellyton@gmail.com

Cursores Explcitos
DECLARE v_Department classes.department%TYPE; v_Course classes.course%TYPE; CURSOR c_AllClasses IS SELECT * FROM classes; v_ClassesRecord c_AllClasses%ROWTYPE; BEGIN OPEN c_AllClasses; -- This is a legal FETCH statement, returning the first -- row into a PL/SQL record which matches the select list -- of the query. FETCH c_AllClasses INTO v_ClassesRecord; -- This FETCH statement is illegal, since the select list -- of the query returns all 7 columns in the classes table -- but we are only fetching into 2 variables. -- This will raise the error "PLS-394: wrong number of values -- in the INTO list of a FETCH statement". FETCH c_AllClasses INTO v_Department, v_Course; CLOSE c_AllClasses ; END;

Kellyton Campos Feitosa

65

kellyton@gmail.com

Parmetros de Cursor Explcito


DECLARE CURSOR c_Classes( p_Department classes.department%TYPE, p_Course classes.course%TYPE ) IS SELECT * FROM classes WHERE department = p_Department AND course = p_Course; BEGIN OPEN c_Classes('HIS', 101); .... END;

Kellyton Campos Feitosa

66

kellyton@gmail.com

Atributos de Cursor Explcito


%ISOPEN (BOOLEAN): 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. Para os cursores implcitos, a referncia aos atributos realizada atravs da utilizao do prefixo sql. Ex.: sql%rowcount

Kellyton Campos Feitosa

67

kellyton@gmail.com

Loop Simples de cursor


DECLARE v_StudentID v_FirstName v_LastName students.id%TYPE; students.first_name%TYPE; students.last_name%TYPE;

CURSOR c_HistoryStudents IS SELECT id, first_name, last_name FROM students WHERE major = 'History'; BEGIN OPEN c_HistoryStudents; LOOP FETCH c_HistoryStudents INTO v_StudentID, v_FirstName, v_LastName; EXIT WHEN c_HistoryStudents%NOTFOUND; INSERT INTO registered_students (student_id, department, course) VALUES (v_StudentID, 'HIS', 301); INSERT INTO temp_table (num_col, char_col) VALUES (v_StudentID, v_FirstName || ' ' || v_LastName); END LOOP; CLOSE c_HistoryStudents; END;

Kellyton Campos Feitosa

68

kellyton@gmail.com

Loop WHILE de cursor


DECLARE CURSOR c_HistoryStudents IS SELECT id, first_name, last_name FROM students WHERE major = 'History'; v_StudentData c_HistoryStudents%ROWTYPE; BEGIN OPEN c_HistoryStudents; FETCH c_HistoryStudents INTO v_StudentData; WHILE c_HistoryStudents%FOUND LOOP INSERT INTO registered_students (student_id, department, course) VALUES (v_StudentData.ID, 'HIS', 301); INSERT INTO temp_table (num_col, char_col) VALUES (v_StudentData.ID, v_StudentData.first_name || ' ' || v_StudentData.last_name); FETCH c_HistoryStudents INTO v_StudentData; END LOOP; CLOSE c_HistoryStudents; END;

Kellyton Campos Feitosa

69

kellyton@gmail.com

Loops FOR de cursor


DECLARE CURSOR c_HistoryStudents IS SELECT id, first_name, last_name FROM students WHERE major = 'History'; BEGIN FOR v_StudentData IN c_HistoryStudents LOOP INSERT INTO registered_students (student_id, department, course) VALUES (v_StudentData.ID, 'HIS', 301); INSERT INTO temp_table (num_col, char_col) VALUES (v_StudentData.ID, v_StudentData.first_name || ' ' || v_StudentData.last_name); END LOOP; END;
*Open, fetch e close so automticas e mais rpidos.

Kellyton Campos Feitosa

70

kellyton@gmail.com

Loops FOR implcitos

BEGIN FOR v_StudentData IN ( SELECT id, first_name, last_name FROM students WHERE major = 'History') LOOP INSERT INTO registered_students (student_id, department, course) VALUES (v_StudentData.ID, 'HIS', 301); INSERT INTO temp_table (num_col, char_col) VALUES (v_StudentData.ID, v_StudentData.first_name || ' ' || v_StudentData.last_name); END LOOP; END;

Kellyton Campos Feitosa

71

kellyton@gmail.com

NO_DATA_FOUND versus %NOTFOUND


A exceo NO_DATA_FOUND levantada apenas em instrues SELECT... INTO, quando nenhuma linha retornada. Quando nenhuma linha retornada por um cursor explcito ou uma instruo UPDATE ou DELETE, o atributo %NOTFOUND configurado como TRUE, no levantando a exceo NO_DATA_FOUND.

Kellyton Campos Feitosa

72

kellyton@gmail.com

Cursores SELECT FOR UPDATE


SELECT ... FROM ... FOR UPDATE [OF colunas] [{NOWAIT | WAIT n}] --Curso implcito

DECLARE CURSOR c_AllStutends IS SELECT * FROM students FOR UPDATE OF first_name, last_name; --Cursor explcito

* O select for update tambm pode ser utilizado para cursores implcitos * OF colunas, server para indicar quais tabelas deseja bloquear.
Kellyton Campos Feitosa

73

kellyton@gmail.com

Clusula WHERE CURRENT OF

{UPDATE | DELETE} tabela WHERE CURRENT OF cursor

Kellyton Campos Feitosa

74

kellyton@gmail.com

Clusula WHERE CURRENT OF


DECLARE v_NumCredits classes.num_credits%TYPE; CURSOR c_RegisteredStudents IS SELECT * FROM students WHERE id IN (SELECT student_id FROM registered_students WHERE department= 'HIS' AND course = 101) FOR UPDATE OF current_credits; BEGIN FOR v_StudentInfo IN c_RegisteredStudents LOOP SELECT num_credits INTO v_NumCredits FROM classes WHERE department = 'HIS' AND course = 101; UPDATE students SET current_credits = current_credits + v_NumCredits WHERE CURRENT OF c_RegisteredStudents; END LOOP; COMMIT; END;

Kellyton Campos Feitosa

75

kellyton@gmail.com

COMMIT dentro de um Loop de cursor FOR UPDATE


Quando houver um COMMIT dentro de um loop de cursor SELECT ... FOR UPDATE, quaisquer tentativa de busca aps o COMMIT retornar erro ORA-1002, pois o cursor invalidado aps essa operao, para liberar os bloqueios nas linhas das tabelas.

Kellyton Campos Feitosa

76

kellyton@gmail.com

Variveis de cursor

TYPE nome_do_tipo IS REF CURSOR; nome_do_tipo: o nome do novo tipo de referncia

OPEN varivel_de_cursor FOR instruo_select;

Kellyton Campos Feitosa

77

kellyton@gmail.com

Variveis de cursor
set serveroutput on; DECLARE TYPE TMeuCursor IS REF CURSOR; v_Cursor TMeuCursor; v_EmpRec emp%ROWTYPE; v_DeptRec dept%ROWTYPE; BEGIN --Utilizar tabela EMP OPEN v_Cursor FOR select * from emp; FETCH v_Cursor INTO v_EmpRec; DBMS_OUTPUT.PUT_LINE(v_EmpRec.empno||'-'|| v_EmpRec.ename); CLOSE v_Cursor; --Utilizar tabela DEPT OPEN v_Cursor FOR select * from dept; FETCH v_Cursor INTO v_DeptRec; DBMS_OUTPUT.PUT_LINE(v_DeptRec.deptno||'-'|| v_DeptRec.dname); CLOSE v_Cursor; end;

Kellyton Campos Feitosa

78

kellyton@gmail.com

Exerccios

Kellyton Campos Feitosa

79

kellyton@gmail.com

Parte IV

Kellyton Campos Feitosa

80

kellyton@gmail.com

Criando Procedures, Funes e Pacotes


Requisitos: Ter o privilgio CREATE PROCEDURE, para criar procedimentos e funes Ter o privilgio DEBUG CONNECT SESSION, para debugar os prprios procedimentos e funes.

Kellyton Campos Feitosa

81

kellyton@gmail.com

Procedures
Quando a procedure criada, ela primeiramente compilada e ento armazenada o banco de dados. Este cdigo compilado pode ser executado de outro blobo PL/SQL. Parmetros podem ser passados quando uma procedure chamada.

Kellyton Campos Feitosa

82

kellyton@gmail.com

Criando uma procedure


CREATE [OR REPLACE] PROCEDURE nome_de_procedure [(argumento [{IN | OUT| IN OUT}] tipo)] {IS | AS} corpo_de_procedure

CREATE OR REPLACE PROCEDURE nome_da_procedure [lista_de_parametros] AS /* A seo declarativa entra aqui*/ BEGIN /* A seo executavel entra aqui*/ EXCEPTION /* A seo de exceo entra aqui*/ END [nome_da_procedure];

Kellyton Campos Feitosa

83

kellyton@gmail.com

Retornando registros atravs de um procedimento armazenado


Script: Parte
IV - Procedure para retornar resultset.sql

Kellyton Campos Feitosa

84

kellyton@gmail.com

Funes
Uma funo bem semelhante a uma procedure, entretanto uma chamada de procedure uma instruo PL/SQL por si prpria, enquanto uma chamada de funo chamada como parte de uma expresso.

Kellyton Campos Feitosa

85

kellyton@gmail.com

Criando uma funo

CREATE [OR REPLACE] FUNCTION nome_de_funo [(argumento [{IN | OUT| IN OUT}] tipo)] , ... argumento [{IN | OUT| IN OUT}] tipo)] RETURN tipo_de_retorno {IS |AS} corpo_da_funo

Kellyton Campos Feitosa

86

kellyton@gmail.com

Funes e a instruo RETURN


utilizada para retornar o controle para o ambiente de chamada com um valor.

CREATE OR REPLACE FUNCTION f_par(p_valor IN NUMBER) RETURN NUMBER AS BEGIN IF MOD(p_valor, 2) = 0 THEN RETURN 1; --O valor do parmetro par. ELSE RETURN 0; --O valor do parmetro impar. END IF; END f_par;

Kellyton Campos Feitosa

87

kellyton@gmail.com

Eliminando Procedures e Funes


A sintaxe para descartar uma procedure : DROP PROCEDURE nome_de_procedure; A sintaxe para descartar uma funo : DROP FUNCTION nome_de_funo;

Kellyton Campos Feitosa

88

kellyton@gmail.com

Parmetros de subprograma (Procedures e funes)


As procedures e funes podem receber parmetros por diferentes modos e podem ser passados por valor ou por referencia. Por padro, a PL/SQL passar parmetros IN por referncia e parmetros OUT e IN OUT por valor Os parmetros formais podem ter trs modos - IN, OUT, ou IN OUT. Se o modo no for especificado, o parametro IN adotado como padro. O modo IN no permite alterao do valor.

Kellyton Campos Feitosa

89

kellyton@gmail.com

Parmetros de subprograma (Procedures e funes)


Modo IN Descrio
O valor do parmetro real passado para a procedure quando a procedure invocada. Dentro da procedure, o parmetro formal atua como uma constante PL/SQL - ele considerado de leitura e no pode ser alterado. Quando a procedure conclui e o controle retorna ao ambiente de chamada, o parmetro real no alterado. Qualquer valor que o parametro real tenha, ignorado quando a procedure chamada. Dentro da procedure, o parametro formal atua como uma variavel nao inicializada PL/SQL e, portanto tem um valor NULL. Ele pode ser lido e escrito. Quando a procedure conclui e o controle retorna ao ambiente de chamada, o contedo do parametro formal atribuido ao paramentro real. Combina IN e OUT. O valor do parametro real passado para a procedure quandoa procedure invocada. Dentro da procedure, o parametro formal atua como uma varivel inicializada e poder ser lido e gravado. Quando a procedure conclui e o controle retorna ao ambiente de chamada, o conteudo do parametro formal atribuido ao parametro real.

OUT

IN OUT

O parametro real que corresponde a um parametro IN OUT ou OUT deve ser uma variavel e nao pode ser uma expressao ou um constante

Kellyton Campos Feitosa

90

kellyton@gmail.com

Parmetros de subprograma (Procedures e funes)

CREATE OR REPLACE FUNCTION f_par(p_valor IN NUMBER) RETURN NUMBER AS BEGIN IF MOD(p_valor, 2) = 0 THEN RETURN 1; ELSE RETURN 0; END IF; END f_par;

Kellyton Campos Feitosa

91

kellyton@gmail.com

Restries quanto aos parmetros formais


Na declarao de uma procedure : ilegal restringir com um comprimento os parmetros: CHAR VARCHAR2 ilegal restringir com uma preciso e/ou escala o parmetro: NUMBER

Kellyton Campos Feitosa

92

kellyton@gmail.com

Parmetros de %TYPE e de procedure

Embora os parmetros formais no possam ser declarados com restries, eles podem ser restringidos utilizando %TYPE.
create or replace PROCEDURE ParameterLength ( p_Parameter1 IN OUT VARCHAR2, p_Parameter2 IN OUT employees.SALARY%type) AS BEGIN p_Parameter2 := 12345; END ParameterLength;

Kellyton Campos Feitosa

93

kellyton@gmail.com

Notao posicional A notao posicional aquela onde os parmetros reais so associados com os parmetros formais por posio.
CREATE OR REPLACE PROCEDURE CallMe( p_ParameterA VARCHAR2, p_ParameterB NUMBER, p_ParameterC BOOLEAN, p_ParameterD DATE) AS BEGIN NULL; END CallMe; / DECLARE v_Variable1 VARCHAR2(10); v_Variable2 NUMBER(7,6); v_Variable3 BOOLEAN; v_Variable4 DATE; BEGIN CallMe(v_Variable1, v_Variable2, v_Variable3, v_Variable4); END;

Kellyton Campos Feitosa

94

kellyton@gmail.com

Notao identificada

A notao posicional aquela onde os parmetros reais so associados com os parmetros formais pelo nome.
DECLARE v_Variable1 VARCHAR2(10); v_Variable2 NUMBER(7,6); v_Variable3 BOOLEAN; v_Variable4 DATE; BEGIN CallMe(p_ParameterA => v_Variable1, p_ParameterC => v_Variable3, p_ParameterD => v_Variable4, p_ParameterB => v_Variable2); END;

Kellyton Campos Feitosa

95

kellyton@gmail.com

Valor padro do parmetro

nome_do_parmetro [modo] tipo_de_parmetro { := | DEFAULT } valor_inicial Ex.: CREATE OR REPLACE PROCEDURE AddNewStudent ( p_FirstName students.first_name%TYPE, p_LastName students.last_name%TYPE, p_Major students.major%TYPE DEFAULT 'Economics') AS BEGIN -- Insert a new row in the students table. Use -- student_sequence to generate the new student ID, and -- 0 for current_credits. INSERT INTO students VALUES (student_sequence.nextval, p_FirstName, p_LastName, p_Major, 0); END AddNewStudent; * Se o parmetro no possuir um valor padro, a definio do seu valor ser obrigatria na chamada ao procedimento/funo. PLS-00306: nmero incorreto de tipos de argumentos na chamada

Kellyton Campos Feitosa

96

kellyton@gmail.com

A instruo CALL
CALL uma instruo SQL. Ela no vlida dentro de um bloco PL/SQL, mas vlida quando executada utilizando a SQL dinmica. Os parnteses so sempre requeridos, mesmo se o subprograma no receber nenhum argumento (ou tiver valores padro para todos os argumentos). A clusula INTO utilizada apenas para as variveis de sida de funes. Os parmetros IN OUT ou OUT so especificados como pare de lista_de_argumentos. No aceita a notao identificada.

Kellyton Campos Feitosa

97

kellyton@gmail.com

A instruo CALL

CALL nome_do_subprograma ([lista_de_argumentos]) [INTO variavel_do_host]; Criando variveis de host no sqlplus


variable teste number begin :teste:=10; end; print teste variable var_cursor REFCURSOR begin open :var_cursor for select last_name from hr.employees; end; print var_cursor

Kellyton Campos Feitosa

98

kellyton@gmail.com

A instruo CALL
CREATE OR REPLACE PROCEDURE CallProc1(p1 IN VARCHAR2 := NULL) AS BEGIN DBMS_OUTPUT.PUT_LINE('CallProc1 called with ' || p1); END CallProc1; CREATE OR REPLACE PROCEDURE CallProc2(p1 IN OUT VARCHAR2) AS BEGIN DBMS_OUTPUT.PUT_LINE('CallProc2 called with ' || p1); p1 := p1 || ' returned!'; END CallProc2; CREATE OR REPLACE FUNCTION CallFunc(p1 IN VARCHAR2) RETURN VARCHAR2 AS BEGIN DBMS_OUTPUT.PUT_LINE('CallFunc called with ' || p1); RETURN p1; END CallFunc; -- Algumas chamadas validas via SQL*Plus. SQL> CALL CallProc1('Hello!'); SQL> CALL CallProc1(); SQL> VARIABLE v_Output VARCHAR2(50); SQL> CALL CallFunc('Hello!') INTO :v_Output; SQL> PRINT v_Output

Kellyton Campos Feitosa

99

kellyton@gmail.com

Procedures versus funes

Ambas podem retornar mais de um valor via parmetros OUT Ambas podem ter sees executveis, declarativas e de tratamento de excees. Ambas podem aceitar valores padro. Ambas podem ser chamados utilizando a notao posicional ou identificada.

Kellyton Campos Feitosa

100

kellyton@gmail.com

Pacotes Permitem agrupar procedimentos e funes em um nico local, onde todos o objetos do pacote so instanciados de uma nica vez.

Kellyton Campos Feitosa

101

kellyton@gmail.com

Especificao de pacote

Tambm conhecida como cabealho de pacote, contm as informaes sobre o contedo do pacote. CREATE [OR REPLACE] PACKAGE nome_de_pacote {IS | AS} definio_de_tipo | especificao_de_procedimento | especificao_de_funo | declarao_de_varivel | declarao_de_exceo | declarao_de_cursor | declarao_de_prgama | END [nome_do_pacote]

Kellyton Campos Feitosa

102

kellyton@gmail.com

Corpo de pacote

O corpo contm o cdigo para as declaraes introdutrias do subprograma no cabealho de pacote. CREATE OR REPLACE PACKAGE BODY nome_de_pacote { IS | AS} ... cdigo_de inicializao; cdigo_das_declaraes END [nome_de_pacote];

* Script: Parte IV - pacote.sql

Kellyton Campos Feitosa

103

kellyton@gmail.com

UTILIZANDO PROCEDURES e FUNES A viso user_source contm o cdigo fonte-original para o objeto. A viso user_errors contm informaes sobre erros de compilao. Observao: na SQL*Plus, o comando show errors consultar user_errors sobre informaes do ltimo objeto criado.

Kellyton Campos Feitosa

104

kellyton@gmail.com

Consideraes sobre subprogramas armazenados

No caso de uma procedure/funo ela pode tornar-se invlida caso uma operao DDL seja realizada em um dos seus objetos dependentes - por exemplo, ao acrescentar uma coluna extra na tabela. Se o objeto dependente for invalidado, o mecanismo PL/SQL tentar recompil-lo automaticamente na prxima vez que for chamado. Obs. As visualizaes de dicionrio de dados user_dependencies, all_dependencies e dba_dependencies listam diretamente o relacionamento entre os objetos de esquema.

Kellyton Campos Feitosa

105

kellyton@gmail.com

Para recompilar manualmente uma procedure, utilize o comando: ALTER PROCEDURE nome_de_procedure COMPILE [DEBUG]; ALTER FUNCTION nome_de_funo COMPILE [DEBUG]; ALTER PACKAGE nome_de_pacote COMPILE [DEBUG]; ALTER PACKAGE nome_de_pacote COMPILE SPECIFICATION; ALTER PACKAGE nome_de_pacote COMPILE BODY; * Se SPECIFICATION e BODY no forem especificados, ambos so compilados.

Kellyton Campos Feitosa

106

kellyton@gmail.com

Privilgio EXECUTE
Para executar procedimentos/funes de outros usurios necessrio ter o privilgio execute sobre esses objetos. Grant execute on hr.f_par to scott

Kellyton Campos Feitosa

107

kellyton@gmail.com

Direito do chamador versus direito do definidor

CREATE [OR REPLACE] FUNCTION nome_de_funo [lista_de_parmetros] RETURN tipo_de_retorno [AUTHID {CURRENT_USER | DEFINER}] {IS | AS} corpo_de_funo; CREATE [OR REPLACE] PROCEDURE nome_de_procedure [lista_de_parmetros] [AUTHID {CURRENT_USER | DEFINER}] {IS | AS} corpo_de_procedure; CREATE [OR REPLACE] PACKAGE nome_da_especificao_do_pacote [AUTHID {CURRENT_USER | DEFINER}] {IS | AS} especificao_de_procedure;

Kellyton Campos Feitosa

108

kellyton@gmail.com

Direito do chamador versus direito do definidor

Se CURRENT_USER for especificado na clusula AUTHID, o objeto ter os direitos do chamador. Se DEFINER for especificado, ento o objeto ter os direitos do definidor. Default -> direitos do definidor. O exemplo a seguir uma procedure de direitos do chamador:

Kellyton Campos Feitosa

109

kellyton@gmail.com

Direito do chamador versus direito do definidor

CREATE OR REPLACE PROCEDURE RecordFullClasses AUTHID CURRENT_USER AS -- Note that we have to preface classes with -- UserA, since it is owned by UserA only. CURSOR c_Classes IS SELECT department, course FROM UserA.classes; BEGIN FOR v_ClassRecord IN c_Classes LOOP -- Record all classes which don't have very much room left -- in temp_table. IF AlmostFull(v_ClassRecord.department, v_ClassRecord.course) THEN INSERT INTO temp_table (char_col) VALUES (v_ClassRecord.department || ' ' || v_ClassRecord.course || ' is almost full!'); END IF; END LOOP; END RecordFullClasses;

Kellyton Campos Feitosa

110

kellyton@gmail.com

Exerccios

Kellyton Campos Feitosa

111

kellyton@gmail.com

Parte V
TRIGGERS DE BANCO DE DADOS

Kellyton Campos Feitosa

112

kellyton@gmail.com

TRIGGERS DE BANCO DE DADOS


Um trigger um bloco pl/sql que executado implicitamente sempre que o evento desencadeador acontece. Os triggers tm vrias utilidades, incluindo: Manter restries complexas de integridade Fazer auditoria das informaes com detalhes Sinalizar automaticamente a outros programas que uma ao precisa acontecer quando so feitas alteraes em uma tabela

Kellyton Campos Feitosa

113

kellyton@gmail.com

TRIGGERS DE BANCO DE DADOS CREATE [OR REPLACE] TRIGGER nome {BEFORE | AFTER | INSTEAD-OF} evento [clusula_de_referncia] [WHEN condio_da_trigger] [FOR EACH ROW] [declare] corpo_de_trigger;

Kellyton Campos Feitosa

114

kellyton@gmail.com

Criando triggers de DML

So acionados em uma operao INSERT, UPDATE ou DELETE de uma tabela de banco de dados. CREATE OR REPLACE TRIGGER update_job_history AFTER UPDATE OF job_id, department_id ON employees FOR EACH ROW BEGIN add_job_history(:old.employee_id, :old.hire_date, sysdate, :old.job_id, :old.department_id); END;

Kellyton Campos Feitosa

115

kellyton@gmail.com

Identificadores de correlao em triggers de nvel de linha (FOR EACH ROW )

Dentro do trigger, voc pode acessar os dados da linha que est sendo processada atualmente, atravs do :NEW.nome_coluna e :OLD.nome_coluna Observe que :OLD NULL para triggers em instrues INSERT, e :NEW NULL para instrues DELETE. Os valores :NEW e :OLD no podem ser alterados para gatilhos do tipo AFTER.

Kellyton Campos Feitosa

116

kellyton@gmail.com

A clusula WHEN

vlida apenas para triggers FOR EACH ROW. A trigger ser executada apenas para aquelas linhas que satisfaam a condio especificada.
CREATE OR REPLACE TRIGGER CheckSalary BEFORE INSERT OR UPDATE OF salary ON employees FOR EACH ROW WHEN (new.salary = 0) BEGIN /* corpo de trigger aqu */ END;

Kellyton Campos Feitosa

117

kellyton@gmail.com

Predicados de trigger: INSERTING, UPDATING e DELETING

CREATE OR REPLACE TRIGGER audt_employee BEFORE INSERT OR DELETE OR UPDATE ON employees FOR EACH ROW begin if inserting then --cdigo para insero end if; if deleting then --cdigo para excluso end if; if updating then --cdigo para atualizao end if; end;

Kellyton Campos Feitosa

118

kellyton@gmail.com

Corpos de triggers

O corpo de um trigger no pode exceder 32K , caso isso ocorra, voc pode reduzi-lo, movendo o cdigo para procedures ou pacotes.
CREATE OR REPLACE TRIGGER secure_employees BEFORE INSERT OR UPDATE OR DELETE ON employees BEGIN secure_dml; END secure_employees;

Kellyton Campos Feitosa

119

kellyton@gmail.com

Privilgios de trigger
H cinco privilgios de sistema que podem ser atribudos aos usurios do banco de dados, so eles: CREATE TRIGGER cria triggers no prprio schema CREATE ANY TRIGGER cria triggers em qualquer schema ALTER ANY TRIGGER altera triggers em qualquer schema DROP ANY TRIGGER Exclui trigger em qualquer schema ADMINISTER DATABASE TRIGGER. Crie database triggers

Kellyton Campos Feitosa

120

kellyton@gmail.com

Views do dicionrio de dados

USER_TRIGGERS ALL_TRIGGER DBA_TRIGGERS

Kellyton Campos Feitosa

121

kellyton@gmail.com

Descartando e desativando triggers

DROP TRIGGER nome_do_trigger; ALTER TRIGGER nome_do_trigger {DISABLE | ENABLE}; ALTER TABLE nome_tabela DISABLE ALL TRIGGERS;

Kellyton Campos Feitosa

122

kellyton@gmail.com

Parte VI RECURSOS AVANADOS

Kellyton Campos Feitosa

123

kellyton@gmail.com

Execute immediate
Script: Parte V - Execute immediate com bind variables.sql

Kellyton Campos Feitosa

124

kellyton@gmail.com

Table Functions
Criando uma tabela dinmicamente

CREATE TYPE numset_t AS TABLE OF NUMBER; CREATE FUNCTION f1(x number) RETURN numset_t PIPELINED IS BEGIN FOR i IN 1..x LOOP PIPE ROW(i); END LOOP; RETURN; END; select * from table(f1(3));

Kellyton Campos Feitosa

125

kellyton@gmail.com

Pacote avanado

Alm dos recursos de linguagem que examinamos nas sees anteriores, a PL/SQL tem vrios pacotes predefinidos, sendo que o pacote UTL_FILE um dos mais utilizados. UTL_FILE, permite a um programa PL/SQL ler e graver dados em arquivos do sistema operacional no servidor.

Kellyton Campos Feitosa

126

kellyton@gmail.com

Utl_file
SQL> CREATE DIRECTORY MEU_DIR AS 'C:\'; Directory created. SQL> DECLARE v_FileHandle UTL_FILE.FILE_TYPE; BEGIN v_FileHandle := UTL_FILE.FOPEN('MEU_DIR', 'utl_file.txt', 'w'); -- Write some lines to the file. UTL_FILE.PUT_LINE(v_FileHandle, 'This is line 1!'); FOR v_Counter IN 2..11 LOOP UTL_FILE.PUTF(v_FileHandle, 'This is line %s!\n', v_Counter); END LOOP; -- And close the file. UTL_FILE.FCLOSE(v_FileHandle); END;

Kellyton Campos Feitosa

127

kellyton@gmail.com

Criptografando o cdigo
Utilize o aplicativo wrap wrap iname=input_file [oname=output_file]

Kellyton Campos Feitosa

128

kellyton@gmail.com