Top Banner
PL/SQL Alexandre Costa Vieira ------------------------------
34

Apostila de PL_SQL - Alexandre

Dec 24, 2015

Download

Documents

elizeucassimiro

SQL
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Apostila de PL_SQL - Alexandre

PL/SQL

Alexandre Costa Vieira ------------------------------

Page 2: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 1

Conteúdo

PREFÁCIO ....................................................................................................................................................2

INTRODUÇÃO .............................................................................................................................................3

VIEW ..............................................................................................................................................................4

CREATE VIEW ..............................................................................................................................................4

BLOCO PL/SQL ...........................................................................................................................................5

COMENTÁRIOS .............................................................................................................................................6

PACOTE DBMS_OUTPUT ..........................................................................................................................6

O ATRIBUTO %TYPE ................................................................................................................................7

CREATE SEQUENCE .................................................................................................................................7

CONTROLE DE FLUXO ............................................................................................................................9

COMANDO IF.........................................................................................................................................9

CREATE TRIGGER ................................................................................................................................... 10

DECLARANDO VARIÁVEIS DENTRO DE UMA TRIGGER ................................................................................. 12

GERANDO UMA MENSAGEM DE ERRO ......................................................................................................... 13

GERAÇÃO AUTOMÁTICA DE CHAVE PRIMÁRIA ............................................................................................ 15

ALTER TRIGGER ......................................................................................................................................... 16

DROP TRIGGER ........................................................................................................................................... 17

CREATE FUNCTION ................................................................................................................................ 17

DROP FUNCTION ......................................................................................................................................... 19

Cursor .................................................................................................................................................... 19

Cursos – For Loop ................................................................................................................................. 21

COMANDO WHILE .. LOOP ................................................................................................................ 22

EXCEPTIONS ............................................................................................................................................... 23

Outros EXCEPTIONS............................................................................................................................ 24

TOO_MANY_ROWS - QUANDO UM SELECT RETORNA MAIS DE UMA LINHA .......................................... 24

OTHERS - QUALQUER TIPO DE ERRO ....................................................................................................... 24

RETORNANDO ERROS ........................................................................................................................ 25

EXCEPTION.......................................................................................................................................... 25

FUNÇÕES DE ERRO ............................................................................................................................... 26

CREATE PROCEDURE .................................................................................................................................. 26

Alter Procedure ..................................................................................................................................... 27

Drop Procedure ..................................................................................................................................... 27

Executando Procedure .......................................................................................................................... 27

CREATE PACKAGE ................................................................................................................................. 28

Create Package Body ............................................................................................................................ 30

Alter Package ........................................................................................................................................ 33

Page 3: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 2

Prefácio

Este curso explora toda a potência da linguagem PL/SQL da ORACLE. PÚBLICO

Todos aqueles que estão tecnicamente envolvidos na criação do ORACLE aplicações ou manutenções desse aplicativo, Programadores, Administradores de Banco de Dados, Analistas e Programadores Sênior. Usuários finais quem deseja estender seus conhecimentos, pode achar o curso benéfico. PRÉ-REQUISITOS

Linguagem SQL e noções de banco de dados ORACLE. OBJETIVOS

No final do curso os alunos estarão aptos para:

• Criar códigos usando a linguagem PL/SQL ORACLE. • Desenvolver PROCEDURES,FUNÇOES e PACKAGES.

MANEIRA DE APRESENTAÇÃO

Este curso é direcionado com combinações tradicionais de seções com médias projeções e seções de demonstrações usando a tela de um projetor. Os alunos terão ampla oportunidade para praticar os tópicos trazidos nas seções anteriores.

HORÁRIO

Este curso exige no mínimo 15 horas divididas em 5 dias, e mais 30 horas de dedicação extra curso para que o aluno possa assimilar os conceitos apresentados em sala de aula.

Page 4: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 3

Introdução Recentemente o perfil de utilização evoluiu novamente e nos vemos diante de novas

necessidades. Estruturas mais complexas como Banco de Dados Distribuídos, grande quantidade de informação, custo de tráfego em rede e Arquitetura Cliente-Servidor são algumas características desse novo perfil. Na Arquitetura Cliente-Servidor, por exemplo, é muito importante manter o tráfego de rede a um mínimo e aumentar a performance do RDBMS de modo que ele possa atender rapidamente as freqüentes transações solicitadas pelo usuário. Com essas especificações, organizar o processamento tornando-se fundamental. Por exemplo, grandes blocos PL/SQL circulando pela rede e sendo compilados e otimizados pelo servidor, a cada nova execução, não é uma boa solução. A melhor idéia é armazenar rotinas dentro do RDBMS e acionar essas rotinas através de chamadas. Em vez de todo um bloco PL/SQL temos circulando pela rede apenas o nome da rotina e seus parâmetros. Além disso o Oracle pode guardar a forma compilada e otimizada dessas rotinas melhorando o tempo de execução. No Oracle isto é um Procedimento Armazenado, ou STORED PROCEDURE.

Page 5: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 4

View View é uma tabela lógica gerada no instante da execução do comando. Para criar uma

view a partir de uma ou mais tabelas usamos o comando Create View. Todas alterações, inserções ou exclusões poderam refletir nas tabelas desde que cada linha da view corresponda a uma linha real da tabela.

Create View

Sintaxe

CREATE [OR REPLACE][FORCE | NOFORCE] VIEW [schema.]view[(alias[,alias]...)]

AS subquery

[[WITH CHECK OPTION [CONSTRAINT constraint]] | [WITH READ ONLY]]

Parâmetros

OR REPLACE Recria a view se ela já existir.

FORCE Cria a view mesmo se o objeto referenciado não existir ou o usuário não possuir os privilégios sobre este objeto.

NOFORCE Cria a view somente se o objeto referenciado não existir ou o usuário não possuir os privilégios sobre este objeto.

Schema Usuário dono da view

View Nome da view

alias Especifica nomes para as expressões selecionadas através da query formadora

AS subquery Qualquer comando SELECT, sem as cláusulas ORDER BY ou FOR UPDATE , que dará origem às colunas da view.

WITH CHECK OPTION

Força a aceitar somente comandos INSERT ou UPDATE de linhas que continuem aparecendo na view.

CONSTRAINT O nome associado à check option constraint

WITH READ ONLY

Não permite a execução de comandos INSERT ou UPDATE sobre a view

Page 6: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 5

Exemplo I

O comando seguinte cria uma view da tabela EMP. Esta view mostra os funcionários do departamento 20 e seu salário anual:

CREATE VIEW dept20

AS SELECT ename, sal*12 annual_salary

FROM emp

WHERE deptno = 20

Exemplo II

Este exemplo cria uma view chamada ANALISTAS, com restrição na alteração do cargo:

CREATE VIEW analistas (id_number, person, department, position)

AS SELECT empno, ename, deptno, job

FROM emp

WHERE job = 'ANALISTA'

WITH CHECK OPTION CONSTRAINT wco

Exemplo III

Este exemplo cria uma view igual ao exemplo anterior, mas não permite alterações:

CREATE VIEW clerk (id_number, person, department, position)

AS SELECT empno, ename, deptno, job

FROM emp

WHERE job = 'CLERK'

WITH READ ONLY

Bloco PL/SQL Um bloco PL/SQL consiste de um conjunto de instruções SQL (SELECT,INSERT,

UPDATE, DELETE) ou comandos PL/SQL, e desempenha uma função lógica única, afim de resolver um problema específico ou executar um conjunto de tarefas afins. O Bloco PL/SQL também pode ser referenciado com Unidade de Programa PL/SQL. Os blocos PL/SQL são qualificados em bloco anônimo e Stored Procedure.

O bloco anônimo • Não tem nome • Não está armazenado no SGDB • Geralmente está armazenada na aplicação.

Stored SubProgramas • Utiliza a estrutura do bloco anônimo com base. • Estão armazenados no SGDB, • A eles é atribuído um nome que poderá ser utilizado nas aplicações ou por

outros objetos do banco de dados

A estrutura de um bloco PL/SQL é constituida de três seções:

Page 7: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 6

a) SEÇÃO DE DECLAÇÃO (DECLARE) - Nesta seção são definidos os objetos PL/SQL como variáveis, constantes, cursores e exceções definidas pelo usuário que poderão ser utilizadas dentro do bloco.

b) SEÇÃO DE EXECUÇÕES (BEGIN..END;) - Nesta seção contemplará a sequência de comandos PL/SQL e instruções SQL do bloco.

c) SEÇÃO DE TRATAMENTO DE ERRO (EXCEPTION) - Nesta seção serão tratados os erros definidos e levantados pelo próprio bloco e os erros gerados pela execução do bloco (O capítulo 12 abordará o tratamento de exeções no PL/SQL)

Exemplo:

[DECLARE -- declarações] BEGIN -- instruções e comnados [EXCEPTION -- tratamentos de erro] END;

Comentários Os comentários em PL/SQL são de dois tipos

a) Uma Linha: utiliza-se o delimitador --. A partir de dois hífens tudo o que for escrito até o final da linha é considerado comentário.

b) Múltiplas linhas: utiliza-se o delimitador /* para abrir e */ para fechar. Tudo e todas as linhas que estiverem entre os dois delimitadores serão ignorados

Exemplo: BEGIN -- comentando apenas uma linha COMANDO1; /* comentando várias linhas */ COMANDO2; COMANDO3; -- o resto será ignorado END;

Pacote DBMS_OUTPUT Na programação PL/SQL não existe nenhuma funcionalidade de entrada ou saída. Para

remediar isso, usaremos no aplicativo SQL*Plus o Supplied Package DBMS_OUTPUT que fornecerá apenas a capacidade de dar saídas para mensagens na tela. Isso é feito por meio de dois passos 1.Permitir a saída no SQL*Plus com o comando set serveroutput SET SERVEROUTPUT {ON | OFF}. Dentro do programa PL/SQL, utilize o procedure DBMS_OUTPUT.PUT_LINE. Essa procedure adicionará o argumento informado ao buffer de saída. Com esses passos completados, a saída impressa na tela do SQL*Plus depois que o bloco for completamente executado. Durante a execução, o buffer é preenchido pelas chamadas de DBMS_OUTPUT.PUT_LINE. O SQL*Plus não recupera o conteúdo do buffer e não o imprime até que o controle retorne para o SQL*Plus, depois que o bloco terminou a execução. Exemplo: SQL> SET SERVEROUTPUT ON SQL> BEGIN 2 DBMS_OUTPUT.PUT_LINE(‘Hello from PL/SQL’);

Page 8: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 7

3 END; 4 / Hello from PL/SQL PL/SQL procedure successfully completed. SQL>

O atributo %TYPE

Declara a variável de acordo com uma coluna definida no Banco de Dados; Exemplo V_ename emp.ename%Type; V_balance number(7,2); V_min_balance v_balance%Type :=10;

Create Sequence Cria uma sequence. Uma sequence é um objeto que permite vários usuários gerarem

valores inteiros sem repetição.

Sintaxe

CREATE SEQUENCE [schema.]sequence

[INCREMENT BY integer]

[START WITH integer]

[MAXVALUE integer]

[MINVALUE integer]

[CYCLE | NOCYCLE]

[CACHE integer | NOCACHE]

[ORDER | NOORDER]

Parâmetros

schema Nome do usuário dono da sequence

Sequence Nome da sequence

INCREMENT BY Indica o intervalo entre os números gerados.

MINVALUE Valor mínimo que a sequence pode assumir

MAXVALUE Valor máximo que a sequence pode assumir

START WITH O primeiro valor gerado pela sequence

CYCLE Indica que esta é uma sequence cíclica. Isto é, recomeçará a contagem quando atingir os

Page 9: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 8

extremos

NOCYCLE Ira incrementando ate atingir o limite estipulado

CACHE Indica quantos valores da sequence o ORACLE ira manter na memória para um acesso mais rápido.

NOCACHE Não terá valores pré alocados

ORDER Garante que o numero gerado pela sequence obedece a ordem de requisição

NOORDER Não garante que os números seqüenciais gerados obedecem à ordem de requisição

Depois de criada a sequence, você pode acessar seus valores nos comandos SQL através das “ pseudo-colunas” abaixo:

CURRVAL

Retorna o ultimo valor da sequence gerado para a sessão atual

NEXTVAL

Incrementa a sequence e retorna o novo valor

Exemplo I O comando seguinte cria uma sequence com incremento de 10 começando do 1:

CREATE SEQUENCE teste_seq

INCREMENT BY 10

Exemplo II

O comando a seguir cria uma sequence com incremento de 1 começando do 11:

CREATE SEQUENCE seq_cod_func

INCREMENT BY 1

START WITH 11;

SELECT seq_cod_func.currval FROM dual;

SELECT seq_cod_func.nextval FROM dual;

Exemplo III

O comando a seguir cria uma sequence começando do 30:

CREATE SEQUENCE seq_cod_cli

Page 10: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 9

START WITH 30;

SELECT seq_cod_cli.currval FROM dual;

SELECT seq_cod_cli.nextval FROM dual;

CONTROLE DE FLUXO

COMANDO IF

1. IF <condição> THEN <comandos> END IF; 2. IF <condição> THEN <comandos> ELSE <comandos> END IF; 3. IF <condição> THEN <comandos> ELSIF <condição> THEN <comandos> END IF; 4. IF <condição> THEN <comandos> ELSIF <condição> THEN <comandos> ELSE <comandos> END IF; 5. IF <condição> THEN IF <condição> THEN <comandos> END IF; END IF; EXEMPLO

DECLARE QUANT NUMBER(3); BEGIN SELECT ES.NR_QTD INTO QUANT FROM ESTOQUE ES WHERE CD_PROD = 30; IF QUANT > 0 AND QUANT < 3000 THEN UPDATE ESTOQUE SET NR_QTD = QUANT + 1

Page 11: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 10

WHERE CD_PROD = 30; ELSIF QUANT >= 3000 THEN INSERT INTO ALERTA(PROD,ERRO) VALUES(30,’MÁXIMO’); ELSE INSERT INTO ALERTA(PROD,ERRO) VALUES(30,’MÍNIMO’); END IF; END;

Create Trigger Cria e habilita triggers. Trigger é um bloco de código PL/SQL associado a uma tabela. Se

um comando SQL for executado sobre esta tabela as triggers são disparadas automaticamente pelo Oracle. Normalmente as regras de negócio são implementadas em triggers.

Sintaxe

CREATE [OR REPLACE] TRIGGER [schema.]trigger

{BEFORE | AFTER}

{DELETE | INSERT | UPDATE [OF column [, column] ...]}

[OR {DELETE | INSERT | UPDATE [OF column [, column] ...]}] ...

ON [schema.]table

[ [REFERENCING { OLD [AS] old [NEW [AS] new]

| NEW [AS] new [OLD [AS] old] } ]

FOR EACH ROW

[WHEN (condition)] ]

pl/sql_block

Parâmetros

OR REPLACE Recria a trigger se esta já existir.

schema Nome do usuário dono da trigger

table Nome da tabela à qual a trigger esta associada

trigger Nome da trigger que esta sendo criada.

BEFORE Indica ao ORACLE para disparar a trigger antes de executar o comando

AFTER Indica ao ORACLE para disparar a trigger depois de executar o comando

DELETE Indica que esta trigger deve ser disparada quando um comando DELETE apagar uma linha da tabela.

INSERT Indica que esta trigger deve ser disparada quando um comando INSERT adicionar uma linha da tabela.

UPDATE OF Indica que esta trigger deve ser disparada quando um comando UPDATE alterar uma das colunas especificadas na clausula OF

REFERENCIN Usado para nomes correlacionados. Você pode usar

Page 12: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 11

G correlação de nomes em blocos PL/SQL e em cláusulas WHEN de uma trigger para fazer referência de antigos e novos valores da linha corrente.

FOR EACH ROW

Indica que a trigger deve ser disparada a cada linha afetada pelo comando

WHEN Contém uma condição SQL que deve ser verdadeira para permitir o disparo da trigger.

pl/sql_block Bloco PL/SQL que indica a ação a ser executada pela TRIGGER

Quando uma trigger é criada para mais que uma operação DML, pode-se utilizar constantes condicionais no corpo da trigger para executar determinado bloco de comandos, dependendo do comando que a disparou. As constantes condicionais são as seguintes:

INSERTING TRUE se o comando que disparou a trigger foi um INSERT.

DELETING TRUE se o comando que disparou a trigger foi um DELETE.

UPDATING TRUE se o comando que disparou a trigger foi um UPDATE.

UPDATING (column_name)

TRUE se o comando que disparou a trigger foi um UPDATE e a coluna column_name foi alterada.

Obtendo o conteúdo dos campos em triggers:

:NEW.Nome_do_Campo

Retorna o conteúdo novo do campo. No DELETE não é utilizado pois não há alteração de valores, consequentemente não há valor novo.

BEFORE

Se a trigger for disparada BEFORE os dados podem ser alterados.

Se a operação for INSERT retornará o valor que poderá ser inserido pelo comando SQL. No UPDATE o comportamento será o mesmo, pois retornará o valor do campo com as alterações que poderão ser feitas.

AFTER

Se a trigger for disparada AFTER os dados não podem ser alterados.

Se a operação for INSERT retornará o valor que foi inserido pelo comando SQL. No UPDATE o comportamento será o mesmo, pois retornará o valor do campo com as alterações que foram feitas.

Page 13: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 12

:OLD.Nome_do_Campo

Retorna o conteúdo antigo do campo e nunca pode ser alterado. No INSERT não é utilizado pois não há valores antigos a inserção.

BEFORE

Se a operação for UPDATE retornará o valor do campo antes da alteração. No DELETE retornará o conteúdo do campo atual.

AFTER Se a operação for UPDATE retornará o valor do campo antes da alteração. No DELETE retornará o conteúdo do campo atual.

Quando existem diversas triggers a serem executadas (before ou after), não se pode dizer qual será a ordem de execução dessas triggers.

Triggers

BEFORE

Constraints

Gravação Triggers

AFTER

Recomenda-se o uso das triggers before para correção dos dados gravados em :new, pois é esse o momento ideal para isso. Consistência de valores, checagem de dados após a gravação e operações similares deve-se usar triggers after.

Declarando variáveis dentro de uma trigger A variável V1 é do tipo numérica.

A variável V2 é do tipo coluna de uma tabela, no exemplo, da tabela ITEM campo VAL_UNITARIO.

A variável V3 é do tipo linha de uma tabela, no exemplo, da tabela ITEM.

CREATE OR REPLACE trg_nome

BEFORE INSERT OR DELETE OR UPDATE ON tabela

FOR EACH ROW

DECLARE

V1 NUMBER;

V2 ITEM.VAL_UNITARIO%TYPE;

V3 ITEM%ROWTYPE;

BEGIN

...

END;

Page 14: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 13

Gerando uma mensagem de erro Usando trigger para restringir operações em uma tabela. No exemplo abaixo, irá exibir

uma mensagem de erro quando a operação é diferente de uma inserção.

CREATE OR REPLACE TRIGGER trg_nome

BEFORE INSERT OR DELETE OR UPDATE ON tabela

FOR EACH ROW

BEGIN

IF NOT INSERTING THEN

RAISE_APPLICATION_ERROR (-20000, 'Erro: não é permitida está operação!');

END IF;

END;

Exemplo I

O exemplo seguinte usa as constantes condicionais para determinar qual tipo de comando SQL foi feito na tabela classified_table:

CREATE TRIGGER audit_trigger

BEFORE INSERT OR DELETE OR UPDATE ON classified_table

FOR EACH ROW

BEGIN

IF INSERTING THEN

INSERT INTO audit_table

VALUES (USER || ' inseriu ' || ' novo valor: ' || :new.campo);

ELSIF DELETING THEN

INSERT INTO audit_table

VALUES (USER || ' apagou ' || ' valor antigo: ' || :old.campo);

ELSIF UPDATING('FORMULA') THEN

INSERT INTO audit_table

VALUES (USER || ' alterou ' || ' formula antiga: ' || :old.formula || ' formula nova: ' || :new.formula);

ELSIF UPDATING THEN

INSERT INTO audit_table

Page 15: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 14

VALUES (USER || ' alterou ' || ' valor antigo: ' || :old.campo || ' valor novo: ' || :new.campo);

END IF;

END;

Exemplo II

Este exemplo cria uma trigger que só permite alterações na tabela EMP sejam feitas somente no horário comercial:

CREATE TRIGGER scott.emp_permit_changes

BEFORE DELETE OR INSERT OR UPDATE ON scott.emp

DECLARE

dummy INTEGER;

BEGIN

/* Se for Sábado ou Domingo retorna ERROR.*/

IF (TO_CHAR(SYSDATE, 'DY') = 'SAT' OR TO_CHAR(SYSDATE, 'DY') = 'SUN') THEN

raise_application_error( -20501, 'Você não pode alterar funcionário no fim de semana');

END IF;

/*Se o horário atual for menor que 8:00AM ou maior 6:00PM, então retorna ERRO. */

IF (TO_CHAR(SYSDATE, 'HH24') < 8 OR TO_CHAR(SYSDATE, 'HH24') >= 18)

THEN raise_application_error( -20502, 'Só pode alterar funcionário no horário do expediente');

END IF;

END;

Exemplo III

Este exemplo cria uma trigger que quando um novo funcionário é adicionado ou o salário de um já existente é alterado, garante que o valor do salário esteja na faixa da função do funcionário:

CREATE TRIGGER scott.salary_check

BEFORE INSERT OR UPDATE OF sal, job ON scott.emp

FOR EACH ROW

WHEN (new.job <> 'PRESIDENT')

DECLARE

Page 16: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 15

minsal NUMBER;

maxsal NUMBER;

BEGIN

/* Pega o menor e o maior salário da função. */

SELECT minsal, maxsal INTO minsal, maxsal FROM sal_guide

WHERE job = :new.job;

/* Se o salário é menor que o mínimo ou maior que o máximo gera um ERRO */

IF (:new.sal < minsal OR :new.sal > maxsal) THEN

raise_application_error( -20601, 'Salario ' || :new.sal || ' fora da faixa para ' || :new.job || ' do funcionario ' || :new.ename );

END IF;

END;

Geração automática de chave primária Os valores NEXTVAL e CURRVAL de uma sequence podem ser usados em uma trigger

para gerar chave primária automática.

Exemplo I

O comando seguinte incrementa a sequence ZSEQ e retorna o novo valor:

CREATE TRIGGER GeraNumeroNota

BEFORE INSERT ON Nota_Fiscal

FOR EACH ROW

BEGIN

SELECT seq_nota_fiscal.nextval INTO :new.nr_nota FROM dual;

END;

Exemplo II

Gera chave primária para a tabela Cliente caso não tenha sido informado no comando de inserção.

CREATE OR REPLACE TRIGGER trg_cliente_pk

BEFORE INSERT ON CLIENTE

FOR EACH ROW

BEGIN

IF :NEW.cod_cli is null THEN

SELECT seq_cliente.nextval INTO :new.cod_cli FROM dual;

Page 17: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 16

END IF;

END;

Exemplo III

Gera chave primária para a tabela Fatura , mas dependendo da última fatura da filial na tabela FILIAL.

CREATE OR REPLACE TRIGGER trg_fatura_pk

BEFORE INSERT ON FATURA

FOR EACH ROW

BEGIN

SELECT nvl(curr_fat, 0) + 1 INTO :next_nr FROM FILIAL

WHERE cod_fil = :new.cod_fil;

END;

Outra maneira de implementar a trigger anterior:

CREATE OR REPLACE TRIGGER trg_fatura_pk

BEFORE INSERT ON FATURA

FOR EACH ROW

BEGIN

UPDATE filial SET curr_fat = curr_fat +1

WHERE cod_fil = :new.cod_fil

RETURNING curr_fat INTO :NEW.nr_fat;

END;

Alter Trigger Para habilitar ou desabilitar uma trigger.

Sintaxe

ALTER TRIGGER [schema.]trigger

{ ENABLE

| DISABLE }

Page 18: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 17

Parâmetros

schema Usuário dono da trigger.

Trigger Nome da trigger a ser alterada.

ENABLE Habilita a trigger.

DISABLE Desabilita a trigger.

Exemplo

ALTER TRIGGER reorder

DISABLE;

ALTER TRIGGER reorder

ENABLE;

Drop Trigger Para remover uma trigger da base.

Sintaxe

DROP TRIGGER [schema.]trigger

Parâmetros

schema Usuário dono da trigger.

trigger Nome da trigger a ser removida.

Exemplo

Este exemplo remove uma trigger do usuário RUTH:

DROP TRIGGER ruth.reorder

Create Function Cria uma função de usuário.

Uma função é um conjunto de comandos PL/SQL normalmente utilizados para efetuar um cálculo ou manipular um valor. Podem ser utilizadas dentro de comandos SQL. Nas functions

Page 19: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 18

não é aconselhavel fazer alterações no status da base, por exemplo, incluir, alterar, deletar registros. Ao alterar o status do banco, esta função não poderá ser utilizada dentro de comandos SQL. Assim a utilidade da function é descaracterizada, assumindo a função da procedure que é própria para alterar dados.

Sintaxe

CREATE [OR REPLACE] FUNCTION [schema.]function

[ (argument [IN] datatype

[, argument [IN] datatype] ...)]

RETURN datatype

{IS | AS} pl/sql_subprogram_body

Parâmetros

OR REPLACE Recria a função se esta já existir.

schema Dono da função.

function Nome da função

argument Nome de um parâmetro da função.

IN Indica que você pode fornecer um valor no momento da chamada da função.

datatype É o tipo de dado do parâmetro

RETURN datatype

Especifica o tipo de dado que a função deve retornar.

pl/sql_subprogram_body

É o código da função.

Exemplo I

Função que calcula a media dos salário de um determinado departamento:

CREATE FUNCTION cal_media(p_deptno IN NUMBER)

RETURN NUMBER IS v_media number;

BEGIN

SELECT avg(sal)

INTO v_media

FROM emp

WHERE dept_no = p_deptno;

RETURN(v_media);

END;

A utilização da função criada acima em um comando SQL:

Page 20: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 19

SELECT cal_media(deptno) FROM dept;

Exemplo II

CREATE OR REPLACE FUCTION media(p_dept number DEFAULT -1)

RETURN NUMBER IS v_media number;

BEGIN

IF p_dept = -1 then

SELECT avg(salario) INTO v_media

FROM funcionario;

ELSE

SELECT avg(salario) INTO v_media

FROM funcionario WHERE cod_dep = p_dept;

END IF;

RETURN (v_media);

END;

Drop Function

Remove uma função da base.

Exemplo

DROP FUNCTION cal_media;

Cursor

Permite uma navegação registro a registro nas linhas retornadas por um comando SELECT.

Sintaxe

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

IS select_statement;

Page 21: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 20

Exemplo I

DECLARE

my_sal emp.sal%TYPE;

factor INTEGER:=2;

CURSOR c1(p_Job varchar2) IS SELECT factor*sal FROM emp

WHERE job=p_Job;

BEGIN

...

OPEN c1(‘ANALISTA’);

LOOP

FETCH c1 INTO my_sal;

EXIT WHEN c1%NOT FOUND;

...

END LOOP;

CLOSE c1;

END;

Page 22: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 21

Exemplo II

DECLARE

Cursor c_cliente IS

Select * from Clientes order by Nome_Cli;

Cursor c_Fatura(p_cli number) IS

Select * from Fatura where cod_cli = p_cli;

R_Cliente c_cliente%rowtype;

R_Fatura c_fatura%rowtype;

BEGIN

OPEN c_cliente;

LOOP

FETCH c_cliente INTO R_cliente;

EXIT When c_cliente%NOT FOUND;

OPEN c_fatura(R_cliente.cod_cli);

DBMS_OUTPUT.PUT_LINE (R_cliente.Nome);

LOOP

FETCH c_fatura INTO R_fatura;

EXIT When c_Fatura%NOT FOUND;

DBMS_OUTPUC.PUT_LINE (R_Fatura.Data);

END LOOP;

CLOSE c_Fatura;

END LOOP;

CLOSE c_Cliente;

END;

Cursos – For Loop

Permite uma navegação registro a registro nas linhas retornadas por um comando SELECT, sem a necessidade de uma definição prévia.

Exemplo I

DECLARE

BEGIN

...

For R1 in (SELECT factor*sal FROM emp WHERE job=p.job) LOOP

...

Page 23: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 22

END LOOP;

END;

Exemplo II

DECLARE

BEGIN

For R_cliente IN (Select * from Cliente order by Nome_cli)

LOOP

DBMS_OUTPUT.PUT_LINE(R_cliente.Nome_Cli);

For R_Fatura IN (Select * from Fatura

Where cod_cli = R_Cliente.cod_cliente) LOOP

DBMS_OUTPUT.PUT_LINE(...);

END LOOP;

END LOOP;

END;

COMANDO WHILE .. LOOP

DECLARE X NUMBER(3); Y VARCHAR2(30); K DATE; J NUMBER(3); BEGIN X:= 0; WHILE X<= 100 LOOP K:= SYSDATE-X; Y := 30; INSERT INTO TESTE VALUES (X,Y,K); X := X + 1; END LOOP; COMMIT; END;

Page 24: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 23

Exceptions Bloco de tratamento de erros.

Sintaxe

DECLARE

past_due EXCEPTION;

BEGIN

...

...

IF ... THEN

RAISE past_due; - esse não é tratado

END IF;

...

EXCEPTION

WHEN past_due THEN - não suporta exceções HANDLE

...

WHEN OTHERS THEN

...

END;

Exemplo

DECLARE

deadlock_detected EXCEPTION ;

PRAGMA EXCEPTION_INIT (deadlock_detected,-60);

BEGIN

...

raise_application_error(-60,’Mensagem do Usuario’);

...

EXCEPTION

WHEN deadlock_detected THEN

... - tratamento do erro

...

END;

DECLARE minha_excep EXCEPTION; Não são todos os erros que tem exception, para poder fazer o tratamento de erro deles é preciso criar

Page 25: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 24

exception e vincular o número do erro com a exception criada.

PRAGMA EXCEPTION_INIT (nome_da_exception, num_erro_relacionado)

Relaciona o número do erro com a exception criada no declare.

RAISE_APPLICATION_ERROR(

-60,’Mensagem de Erro’);

Provoca o erro mostrando a mensagem e o número fornecidos.

Outros EXCEPTIONS

NO_DATA_FOUND - Quando um select não retorna nenhuma linha

TOO_MANY_ROWS - Quando um select retorna mais de uma linha

OTHERS - Qualquer tipo de erro

DECLARE NOME CHAR(15); CARGO CHAR(10); BEGIN SELECT ENAME, JOB INTO NOME, CARGO FROM EMP WHERE EMPNO = 1111; EXCEPTION WHEN NO_DATA_FOUND THEN INSERT INTO PROBLEMA (ERRO,DTERRO) VALUES (‘REGISTRO INEXISTENTE’,SYSDATE); WHEN TOO_MANY_ROWS THEN INSERT INTO PROBLEMA (ERRO,DTERRO) VALUES (‘MUITOS REGISTROS’,SYSDATE); WHEN OTHERS THEN INSERT INTO PROBLEMA (ERRO,DTERRO) VALUES (‘OUTRO ERRO QUALQUER’,SYSDATE); END;

Page 26: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 25

OUTRO EXEMPLO DECLARE NM VARCHAR2(30); BEGIN SELECT NOME INTO NM FROM TESTE WHERE IDADE=30; DBMS_OUTPUT.PUT_LINE(NM); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('IDADE INEXISTENTE'); WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('MULTIPLAS LINHAS'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('OUTRA SAIDA'); END;

RETORNANDO ERROS

SQLERR - Retorna o número do erro SQLERRM – Retorna o número e a descrição do erro

Exemplo BEGIN INSERT INTO TESTE VALUES (50,45,SYSDATE); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE('ERRO - '||SQLERRM); END;

EXCEPTION

n DUP_VAL_ON_INDEX - Chave Duplicada n INVALID_CURSOR - Operação Ilegal com Cursor n INVALID_NUMBER - Conversão inválida p/numérico n LOGIN_DENIED - Usuário/Senha Inválida n NO_DATA_FOUND - Nenhuma linha retornada n NOT_LOGGED_ON - Usuário não conectado

OTHERS - Erro não declarado em exceptions n PROGRAM_ERROR - Problema Interno n STORAGE_ERROR - Falta de Memória n TIMEOUT_ON_RESOURCE - Tempo de espera n TOO_MANY_ROWS - Retorna Muitas Linhas n TRANSACTION_BACKED_OUT - Volta Atrás uma transação n VALUE_ERROR - Erro Conversão,Expressão

ZERO_DIVIDE - Divisão por zero

Page 27: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 26

FUNÇÕES DE ERRO sqlerrm, sqlcode

Create Procedure Para criar uma procedure. Uma procedure é um grupo de comandos PL/SQL que realizam uma tarefa.

Sintaxe

CREATE [OR REPLACE] PROCEDURE [schema.]procedure

[(argument[IN I OUT I IN OUT] datatype

[,argument [ IN I OUT I IN OUT] datatype]...)]

{IS I AS} pl/sql_subprogram_body

Parâmetros

OR REPLACE Recria a procedure se esta já existir.

schema Dono da procedure.

procedure Nome da procedure.

argument Parâmetro da procedure.

IN Indica que você deve especificar o valor deste parâmetro na chamada da procedure.

OUT Indica que a procedure ira retornar um valor por este parâmetro.

IN OUT Através deste parâmetro deve-se informar um valor para procedure e este voltara modificado.

datatype Tipo de dado do parâmetro

pl/sql_subprogram_body

Codificação da procedure

Page 28: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 27

Exemplo que cria a procedure totaliza_nota:

CREATE PROCEDURE totaliza_nota (p_cod_cliente IN number)

AS BEGIN

UPDATE nota_fiscal

SET val_total = val_total + (SELECT sum(valor * qtd) FROM itens WHERE itens.nr_nota = nota_fiscal.nr_nota)

dt_processamento = sysdate

WHERE dt_processamento is NULL and cod_cliente = p_cod_cliente;

COMMIT;

END;

Alter Procedure

Para recompilar uma procedure.

Sintaxe

ALTER PROCEDURE [schema.]procedure COMPILE

Drop Procedure

Para remover uma procedure da base.

Sintaxe

DROP PROCEDURE [schema.]procedure

Executando Procedure

Exemplo

BEGIN

NomeProc(Param);

END;

Ou

EXEC NomeProc(Param);

Page 29: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 28

Dentro de um bloco:

BEGIN

NomeProc(Param);

END;

Create Package Cria uma package. Uma package é a especificação de uma coleção de procedures, functions, e outros objetos de programa com objetivos afins. Parte pública da Package, visível para o mundo externo.

Sintaxe

CREATE [OR REPLACE] PACKAGE [schema].package

{IS I AS} pl/sql_package_spec

Parâmetros

OR REPLACE Recria a package se esta já existe

schema Nome do usuário dono da package.

package Nome da packge.

pl/sql_package_spec É a especificação da package.

Exemplo

Este comando cria a package EMP_MGMT:

CREATE PACKAGE emp_mgmt AS

FUNCTION hire(ename VARCHAR2, job VARCHAR2, mgr NUMBER,

sal NUMBER, comm NUMBER, deptno NUMBER)

RETURN NUMBER;

FUNCTION create_dept(dname VARCHAR2, loc VARCHAR2)

RETURN NUMBER;

PROCEDURE remove_emp(empno NUMBER);

PROCEDURE remove_dept(deptno NUMBER);

PROCEDURE increase_sal(empno NUMBER, sal_incr NUMBER);

PROCEDURE increase_comm(empno NUMBER, comm_incr NUMBER);

no_comm EXCEPTION;

no_sal EXCEPTION;

END emp_mgmt;

Page 30: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 29

Page 31: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 30

Create Package Body

Cria o corpo de uma package, onde “corpo” é a implementação do código. Parte privada da Package, o mundo externo poderá utilizar as funcionalidades da Package declaradas no passo anterior, mas não visualizará o seu código. No Body da Package poderá ter mais funcionalidades do que a declaração da Package, assim estas não estarão disponíveis para o mundo externo serão visíveis apenas dentro da Package Body.

Sintaxe

CREATE [OR PEPLACE] PACKAGE BODY [schema.]package

{IS | AS} pl/sql_package_body

Parâmetros

OR REPLACE Recria o corpo da package se este já existir

schema Usuário dono da package

package Nome da package a ser implementado.

pl/sql_package_body

Codificação do corpo da package

Exemplo

Este exemplo cria o corpo da packge EMP_MGMT:

CREATE PACKAGE BODY emp_mgmt AS

tot_emps NUMBER;

tot_depts NUMBER;

FUNCTION hire(ename VARCHAR2, job VARCHAR2, mgr NUMBER,

sal NUMBER, comm NUMBER, deptno NUMBER)

RETURN NUMBER IS

new_empno NUMBER(4);

BEGIN

SELECT empseq.NEXTVAL

INTO new_empno

FROM DUAL;

INSERT INTO emp

VALUES (new_empno, ename, job, mgr, sal, comm, deptno,

tot_emps := tot_emps + 1;

RETURN(new_empno);

END;

Page 32: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 31

FUNCTION create_dept(dname VARCHAR2, loc VARCHAR2)

RETURN NUMBER IS

new_deptno NUMBER(4);

BEGIN

SELECT deptseq.NEXTVAL

INTO new_deptno

FROM dual;

INSERT INTO dept

VALUES (new_deptno, dname, loc);

tot_depts := tot_depts + 1;

RETURN(new_deptno);

END;

PROCEDURE remove_emp(empno NUMBER) IS

BEGIN

DELETE FROM emp

WHERE emp.empno = remove_emp.empno;

tot_emps := tot_emps - 1;

END;

PROCEDURE remove_dept(deptno NUMBER) IS

BEGIN

DELETE FROM dept

WHERE dept.deptno = remove_dept.deptno;

tot_depts := tot_depts - 1;

SELECT COUNT(*)

INTO tot_emps

FROM emp;

END;

Page 33: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 32

PROCEDURE increase_sal(empno NUMBER, sal_incr NUMBER) IS

curr_sal NUMBER(7,2);

BEGIN

SELECT sal

INTO curr_sal

FROM emp

WHERE emp.empno = increase_sal.empno;

IF curr_sal IS NULL

THEN RAISE no_sal;

ELSE

UPDATE emp

SET sal = sal + sal_incr

WHERE empno = empno;

END IF;

END;

PROCEDURE increase_comm(empno NUMBER, comm_incr NUMBER) IS

curr_comm NUMBER(7,2);

BEGIN

SELECT comm

INTO curr_comm

FROM emp

WHERE emp.empno = increase_comm.empno

IF curr_comm IS NULL

THEN RAISE no_comm;

ELSE

UPDATE emp

SET comm = comm + comm_incr;

END IF;

END;

END emp_mgmt

Page 34: Apostila de PL_SQL - Alexandre

PL/SQL – ORACLE

[Alexandre Costa Vieira – PL/SQL ORACLE] Página 33

Alter Package

Recompila uma package.

Sintaxe

ALTER PACKAGE [schema.]package

COMPILE [ PACKAGE | BODY]