Você está na página 1de 38

APOSTILA DE ORACLE PL/SQL

PL/SQL A linguagem PL/SQL (Procedural Language/SQL) uma extenso de linguagem procedural da Oracle para SQL, que incorpora recursos de programao, tais como: Declarao de variveis e tipos pr-definidos; Estruturas de seleo e repetio; Procedimentos e funes.

Alm de aceitar a manipulao de dados, ela tambm permite que as instrues de consulta da linguagem SQL sejam includas em unidades procedurais de cdigo e estruturadas em blocos, tornando a linguagem SQL uma linguagem avanada de processamento de transaes. A linguagem PL/SQL estruturada em blocos, os programas podem ser divididos em blocos lgicos. Um bloco PL/SQL dividido em trs sees: DECLARATIVA (opcional) - Seo destinada declarao das variveis, cursores e excees que sero utilizadas no bloco; EXECUTVEL (obrigatria) - tambm conhecida como corpo do programa, rea onde so descritos os passos necessrios para realizao da tarefa. Podem ser utilizadas instrues SQL e/ou PL/SQL; TRATAMENTO DE EXCEES (opcional) - destinada ao tratamento das excees geradas no bloco; devem ser descritas as aes a serem desempenhadas quando ocorrerem erros. 1.1. Blocos Annimos Os blocos annimos no ficam armazenados na base de dados e no podem ser chamados por outros blocos PL/SQL. Eles devem ser compilados a cada utilizao. Pode-se incorporar um bloco annimo em uma aplicao ou pode-se execut-lo interativamente no SQL*Plus. Exemplo da estrutura de um bloco em PL/SQL: DECLARE v_variavel varchar2(5); BEGIN Select nome_coluna into v_variavel from nome_tabela; EXCEPTION When <exception_name> then ... (procedimentos a serem executados quando uma determinada exceo ocorrer.) END; Sobre o cdigo: As palavras chave DECLARE, BEGIN e EXCEPTION no so sucedidas de ponto e vrgula (;), apenas as demais instrues; A palavras-chave BEGIN e END so obrigatrias. Deve-se utilizar uma barra (/) para executar o bloco annimo PL/SQL no buffer do SQL*Plus.

1.1.1. Operadores e delimitadores Operador + * / ** || = > < >= <= ~= ou ^= <> ou != ( ) Descrio
Adio Multiplicao Subtrao Diviso Exponenciao Concatenao Igualdade Comparao maior que Comparao menor que Comparao maior ou igual Comparao menor ou igual Comparao diferente Comparao diferente Incio de expresso Fim expresso

Operador % . : := .. -<< >> ; , /* */

Descrio
Atributo Separador de componentes Cadeia de caracteres Varivel de ligao Atribuio Intervalo Comentrio de linha Incio do texto do label (etiqueta) Delimitador de final do texto do label (etiqueta) Finalizador de instruo Separador de itens Delimitador de cadeia de caracteres (mensagens) Incio de comentrio de linha Delimitador de fim de comentrio de linha

1.1.2. Variveis Os dados podem ser armazenados temporariamente em uma ou mais variveis e podem ser utilizadas para: Manipulao de valores armazenados - As variveis podem ser usadas para clculo e manipulao de outros dados sem acessar o banco de dados, ou seja, aps os valores em memria no h necessidade de outros acessos para complemento da informao j armazenada; Reutilizao - Quando declaradas, podem ser usadas repetidamente em uma aplicao, referenciando-as em outras instrues, incluindo outras instrues declarativas; Facilitar a manuteno Pode-se declarar variveis baseadas na estrutura das colunas das tabelas ou em outras varivies (%TYPE e %ROWTYPE). Se uma definio subjacente for alterada, a declarao da varivel atualizada em tempo de execuo. Isso permite a independncia dos dados, reduz custos de manuteno e permite que os programas se adaptem de acordo com as alteraes realizadas no banco de dados; Passar valores aos subprogramas PL/SQL atravs de parmetros; Exibir os resultados em um bloco PL/SQL atravs de variveis de sada. A declarao e a inicializao das variveis feita na seo declarativa de qualquer subprograma, pacote ou bloco PL/SQL. As declaraes alocam espao de armazenamento para um valor, especificam seus tipos de dados e nomeiam a localizao de armazenamento para que se possa referenci-los. As declaraes podero tambm atribuir um valor inicial e impor a restrio NOT NULL. ATENO: Ao Atribuir novos valores s variveis na seo executvel o valor existente da varivel substitudo pelo novo e necessrio declarar uma varivel antes de referenci-la em outras instrues, incluindo outras instrues declarativas.

1.1.3. Tipos de Variveis Todas as variveis PL/SQL tm um tipo de dados que especifica o formato de armazenamento, restries e uma faixa vlida de valores. A linguagem PL/SQL suporta quatro categorias destes: Escalares - armazenam um nico valor. Os principais tipos de dados so aqueles que correspondem aos tipos de coluna nas tabelas do Oracle Server, por exemplo vachar2, number, char, entre outros; a linguagem PL/SQL tambm suporta variveis booleanas; Compostos comporta o armazenamento de diferentes valores. Os tipos compostos em PL/SQL so registro, tabelas e matrizes; Referenciais - armazenam valores, chamados de indicadores, que designam outros itens de programa. Um exemplo de tipos referenciais o REF CURSOR. Declarao de Variveis Sintaxe: identificador [CONSTANT] tipo de dados [NOT NULL] [:= valor para inicializao | expr default] onde, Identificador: o nome da varivel; Os identificadores no devem ter mais de 30 caracteres. O primeiro caracter deve ser uma letra; os demais podem ser letras, nmeros ou smbolos especiais; No devem ser palavras reservadas nem possuir espaos entre os caracteres. restringe as variveis para que o seu valor no possa ser alterado; as constantes devem ser inicializadas

CONSTANT:

tipo de dados so tipos de dados escalares, compostos, referenciais ou LOB NOT NULL indica preenchimento obrigatrio (variveis NOT NULL devem ser inicializadas). uma expresso PL/SQL que pode ser uma literal, uma outra varivel ou uma expresso que envolve operadores e funes.

expr

ATENO: Para inicializar a varivel utiliza-se operador de atribuio (:=) ou a palavra reservada DEFAULT. Se no for atribudo um valor inicial, a nova varivel conter NULL por default. No aconselhvel identificar uma varivel com nome igual ao nome das colunas de tabela usadas no bloco. Se as variveis PL/SQL ocorrerem nas instrues SQL e tiverem o mesmo nome que uma coluna, o Oracle Server supe que a coluna que est sendo referenciada.

1.1.3.1 Tipos de Dados Escalares Um tipo de dado escalar armazena um valor nico e no possui componentes internos. Os tipos de dados escalares podem ser classificados em quatro categorias: nmero, caractere, data e booleano. Os tipos de dados de caractere e nmero possuem subtipos que associam um tipo bsico a uma restrio. Por exemplo, INTEGER e POSITIVE so subtipos do tipo bsico NUMBER. Segue abaixo exemplo de tipos de Dados Escalares Bsicos:

Tipo de dado VARCHAR2(tamanho) NUMBER(tamanho, preciso) DATE CHAR(tamanho) LONG LONG RAW BOOLEAN BINARY_INTEGER PLS_INTEGER

Descrio Caracteres com tamanho varivel com at 32.767 bytes; no h tamanho default para estas variveis. Nmeros reais ou inteiros Datas e horas entre os perodos de 4712 A.C. e 9999 D.C. Caracteres de tamanho fixo at 32.767 bytes; tamanho default 1 byte. Caracteres com tamanho varivel de at 32.760 bytes, a largura mxima de 2.147.483.647 bytes Dados binrios e strings de byte de at 32.760 bytes; estes dados no so interpretados pelo PL/SQL Um de trs possveis valores: TRUE, FALSE ou NULL Nmeros inteiros entre 2.147.483.647 e 2.147.483.647 Nmeros inteiros entre 2.147.483.647 e 2.147.483.647; estes valores requerem menos armazenamento e so mais rpidos que os valores NUMBER e BINARY_INTEGER

Exemplos: v_nascimento date; v_data date := sysdate + 7; --declarao de varivel e inicializao partir de uma operao aritmtica v_codigo number(2) not null := 10; -- declarao da varivel com a restrio de preenchimento obrigatrio, neste caso preciso atribuir o valor inicial v_UF varchar2(2) := SP; -- declarao e inicializao da varivel com o valor SP; observe que os literais devem ser informados entre apstrofos ( ) v_Loc varchar2(2) default RJ; -- declarao da varivel cujo valor default RJ. v_teste_logico boolean := (v_valor1 < v_valor2); -- declarao da varivel v_teste_logico que ser inicializada com o resultado da expresso (v_valor1 < v_valor2) c_const constant number := 54; -- declarao da constante que est sendo inicializada. O atributo %TYPE pode ser utilizado para declarar variveis com a mesma estrutura de uma tabela ou de uma varivel j existente. Sintaxe: identificador [CONSTANT] {tabela.coluna%type | variavel%type} [NOT NULL] [:= valor para inicializao | expr default] Exemplos: v_nome EMPR_NOME_DS%type; -- declarao da varivel com a mesma estrutura da coluna EMPR_NOME_DS da tabela EMPR. v_balance number(7,2); v_min_balance v_balance%type; -- declarao da varivel com a mesma estrutura da varivel declarada anteriormente.

ATENO: uma boa prtica de programao a adoo de uma conveno de nomeao para variveis, por expl: o prefixo v_ representa uma varivel; c_ representa uma constante. 1.1.4. Variveis de Substituio Alm das variveis declaradas no Bloco PL/SQL existem as variveis de substituio e de ligao. O cdigo PL/SQL no tem capacidade de entrada/sada prpria, para isso pode-se utilizar o ambiente no qual o cdigo PL/SQL estiver sendo executado para passar valores para o bloco, estes valores so passados por meio das variveis de substituio. ATENO: Ao utilizar as variveis de substituio os valores so substitudos no bloco PL/SQL antes que esse bloco seja executado. Por isso, no possvel substituir os diferentes valores para as variveis de substituio usando um loop. Exemplo: ACCEPT p_nome PROMPT Digite o nome do funcionrio... ACCEPT p_sal_mes PROMPT Digite o valor do salario... O comando accept indica que o valor para a varivel de substituio p_nome e p_sal_mes sero fornecidos pelo teclado. O comando PROMPT indica a mensagem que ser exibida para orientar o usurio quanto ao valor a ser digitado. Para atribuir os valores das variveis de substituio para as variveis PL/SQL necessrio a utilizao do & (E comercial). Exemplo: Declare v_nome varchar2(30) := &p_nome; v_sal number(9,2) := &p_sal_mes; 1.1.5. Variveis de ligao Para declarar uma varivel de ligao no ambiente SQL*Plus, utiliza-se o comando VARIABLE. Exemplo: SQL> VARIABLE g_sal_anual NUMBER Estas variveis podem ser declaradas no prompt do SQL ou fora do bloco PL/SQL (antes do declare ou depois da /). Para utilizar estas variveis no bloco PL/ SQL deve-se preced-las de : (dois pontos), para que sejam distinguidas das variveis PL/SQL: Exemplo: :g_sal_anual := v_sal * 12; A exibio dos valores armazenados nestas variveis pode ser feita por meio do comando PRINT. Exemplo: PRINT g_sal_anual Exemplo 1: Calcular o salrio anual de dado funcionrio com base no salrio mensal fornecido pelo usurio. Exibir o resultado.

VARIABLE g_sal_anual NUMBER ACCEPT p_nome PROMPT Nome do funcionario...: ACCEPT p_sal_mes PROMPT Valor do salario...: Declare v_nome varchar2(30) := &p_nome; v_sal number(9,2) := &p_sal_mes; Begin :g_sal_anual := v_sal * 12; END; / PRINT g_sal_annual Para testar o exemplo 1:

Instruo SQL

Bloco PL/SQL

Instruo SQL

Escreva o cdigo utilizando um editor de textos; salve o arquivo com a extenso .sql (p.expl.: exemplo1.sql); no prompt do Sql*Plus digite: @localizao do arquivo\nome do arquivo, por exemplo: SQL>@C:\programas\exemplo1.sql No exemplo 1 foi utilizado o comando PRINT para exibio do resultado do processamento. Uma outra opo para isso a utilizao do pacote DBMS_output e procedimento put_line. Sintaxe: DBMS_output.put_line(mensagem); onde mensagem pode ser: uma cadeia de caracteres, por exemplo: DBMS_output.put_line (O nome do funcionrio ); e neste caso dever ser especificada entre apstrofos. uma varivel ou constante, por exemplo: DBMS_output.put_line (v_sal_anual); ou ambas, por exemplo: DBMS_output.put_line(nome do funcionrio || v_sal_anual); utilizando o operador de concatenao || para unir as duas mensagens. ATENO: Para a utilizao deste pacote necessrio ativ-lo no SQL*Plus por meio da instruo SET SERVEROUTPUT ON. Exemplo 2: Calcular o salrio anual de dado funcionrio com base no salrio mensal fornecido pelo usurio. Exibir o resultado. SET SERVEROUTPUT ON ACCEPT p_nome PROMPT Digite o nome do funcionrio... ACCEPT p_sal_mes PROMPT Digite o valor do salario... Declare v_nome varchar2(30) := &p_nome; v_sal number(9,2) := &p_sal_mes; v_sal_anual number(9,2); Begin v_sal_anual := v_sal * 12; DBMS_output.put_line(O salario anual de || v_nome || || v_sal_anual); END; /

Instruo SQL

Bloco PL/SQL

No exemplo 2 no est sendo utilizada a varivel de ligao g_sal_anual, pois a solicitao da exibio do resultado do processamento est sendo feita na rea executvel do bloco PL/SQL.

1.1.6. Instrues SELECT em PL/SQL Recuperar dados do banco de dados com a instruo SELECT. Sintaxe: SELECT colunas INTO {variveis...| registro} FROM tabela WHERE condio; onde, colunas: Into: lista de colunas que retornaro dados consulta; podem incluir funes de linhas, de grupo ou expresses SQL clusula obrigatria, usada para especificar os nomes das variveis que armazenaro os valores que o SQL retornar a partir da clusula SELECT. Deve-se oferecer uma varivel para cada coluna, seguindo a mesma ordem. nome das varivies que iro armazenar o valor recuperado o registro PL/SQL para armazenar os valores recuperados especifica o nome da tabela do banco de dados composta de nomes de coluna, expresses, constantes e operadores de comparao, incluindo as variveis PL/SQL e operadores.

Variveis: Registro: Tabela: Condio:

Exemplo 3: Recuperar o nome e o cargo do funcionrio para o cdigo indicado. VARIABLE g_nome varchar2(15) VARIABLE g_cargo varchar2(15) DECLARE v_nome EMP.EMPR_NOME_DS%type; v_cargo EMP.EMPR_SERV_DS%type; BEGIN select EMPR_NOME_DS, EMPR_SERV_DS into v_nome, v_cargo from EMPR where EMPR_NUME_NR = 7934; :g_nome := v_nome; :g_cargo := v_cargo; END; / PRINT g_nome PRINT g_cargo ATENO: As instrues SELECT em um bloco PL/SQL as consultas devem retornar apenas uma linha, mais de uma ou nenhuma linha geram mensagens de erro que poder ser tratado. Para consultas que retornam vrias linhas dever ser criado um cursores explcitos, que sero vistos adiante. Exemplo 4: Calcular e exibir a somatria do salrio de todos os funcionrios de um dado departamento. SET SERVEOUTPUT ON DECLARE v_soma_sal EMPR_SALA_VL%TYPE; v_deptno NUMBER NOT NULL := 10; BEGIN SELECT SUM(sal) INTO v_soma_sal FROM empr WHERE deptno = v_deptno;

DBMS_output.put_line(A soma dos salrios do departamento || v_deptno || || v_soma_sal); END; 1.1.7. Aninhamento de blocos e Escopo das variveis As variveis podem ser utilizadas em determinadas reas do programa, um bloco PL/SQL pode ser composto por vrios blocos aninhados (sub-blocos), cada sub-bloco pode possuir suas variveis. No exemplo 5 a varivel valor1 declarada nos 3 sub-blocos que compe o programa, mas em cada bloco o seu valor preservado e no gerado nenhum tipo de conflito pois estas variveis so locais. Exemplo 5: Aninhamento de blocos e escopo de variveis SET SERVEROUTPUT ON DECLARE -- bloco 1 valor1 number(2) := 7; valor2 number(2) := 13; BEGIN -- bloco 1 DECLARE -- bloco 2 valor1 varchar2(30) := 'Valor 1 do bloco 2'; BEGIN -- bloco 2 DECLARE -- bloco 3 valor1 date := sysdate; BEGIN -- bloco 3 DBMS_OUTPUT.PUT_LINE('Valor 1 do bloco 3...' || valor1); END; -- bloco 3 DBMS_OUTPUT.PUT_LINE('Valor 1 do bloco 2...' || valor1); END; -- bloco 2 DBMS_OUTPUT.PUT_LINE('Valor 1 do bloco 1... ' || valor1); END; -- bloco 1 / Resultado da execuo do bloco: SQL> @c:\programas\escopo.sql Valor 1 do bloco 3...12/05/04 Valor 1 do bloco 2...Valor 1 do bloco 2 Valor 1 do bloco 1... 7 1.1.8. Insero de Dados Exemplo 6: Adicionar informaes sobre novos funcionrios na tabela EMPR. DECLARE v_ename EMPR_NOME_DS%type := 'ZE TONHAO'; v_job EMP.EMPR_SERV_DS%type := 'BALCONISTA'; v_deptno EMPR.DEPT_NUME_NR%type := 30; BEGIN Insert into EMPR (EMPR_NUME_NR, EMPR_NOME_DS, EMPR_SERV_DS, DEPT_NUME_NR) values (v_empno, v_ename, v_job, v_deptno); END;

1.1.9. Atualizando Dados Exemplo 7: Aumentar o salrio de todos os funcionrios na tabela EMPR e que sejam Analistas, adicionando 2000 ao valor do salrio. DECLARE v_sal_increase empr_sala_vl%TYPE := 2000; BEGIN UPDATE empr SET empr_sala_vl = empr_sala_vl + v_sal_increase WHERE EMPR_SERV_DS = 'ANALISTA'; END; 1.1.10. Excluso de Dados Exemplo 8: Deletar linhas que pertenam ao departamento 10 da tabela EMPR. DECLARE v_deptno BEGIN DELETE FROM WHERE END; 1.1.11. Controle de Transaes O controle da lgica das transaes realizado com as instrues COMMIT e ROLLBACK, tornando permanentes as alteraes em alguns grupos de bancos de dados e descartando outros. Assim como ocorre com o Oracle Server, as transaes DML so iniciadas no primeiro comando seguindo uma instruo COMMIT ou ROLLBACK e so finalizadas na prxima instruo COMMIT ou ROLLBACK correta. Essas aes podem ocorrer em um bloco PL/SQL ou como resultado dos eventos no ambiente do host (por exemplo, o encerramento de uma sesso SQL*Plus automaticamente compromete a transao pendente). 1.2. Estruturas de Controle As estruturas de controle permitem estabelecer o fluxo lgico de instrues que sero executadas. Para isso podem ser utilizadas as estruturas de controle para repetio de blocos do programa (loop) e as estruturas de controle para avaliao de condies e seleo (if). 1.2.1. Estruturas de seleo As estruturas de seleo possibilitam que o fluxo de processamento das instrues PL/SQL seja direcionado de acordo com a condio especificada. Existem trs maneiras para se utilizar a instruo If:

empr.dept_nume_nr%TYPE := 10; empr dept_nume_nr = v_deptno;

IF (condio) THEN Conjunto de instrues ; END IF; IF(condio) THEN Conjunto de instrues 1; ELSE Conjunto de instrues 2; END IF;

Neste caso, se o teste de avaliao da condio retornar verdadeiro o conjunto de instrues ser realizado, caso contrrio o bloco de seleo encerrado. Neste caso, se o teste de avaliao da condio retornar verdadeiro o conjunto de instrues 1 ser realizado, caso contrrio o ser realizado o conjunto de instrues 2.

IF (condio1 ) THEN Conjunto de instrues 1; ELSIF (condio 2) Conjunto de instrues 2 ; ... ELSE Conjunto de instrues n; END IF;

Neste caso, se o teste de avaliao da condio retornar verdadeiro, o conjunto de instrues 1 ser realizado, seno, ser realizado o teste de avaliao da condio 2. Se o resultado for verdadeiro ser realizado o conjunto de instrues 2, seno, ser realizado o teste avaliao da condio 3, e assim por diante. Caso nenhuma das condies testadas resultar verdadeiro ser realizado o conjunto de instrues previsto aps o ELSE.

onde, condio

THEN instrues ELSIF

ELSE

uma expresso ou varivel Booleana (TRUE, FALSE ou NULL) (Ela est associada a uma seqncia de instrues, que ser executada somente se a expresso produzir TRUE.) uma clusula que associa a expresso Booleana que a precede com a seqncia de instrues posterior pode ser uma ou mais instrues SQL ou PL/SQL. (Elas podem incluir mais instrues IF contendo diversos IFs, ELSEs e ELSIFs aninhados.) uma palavra-chave que introduz uma expresso Booleana. (Se a primeira condio produzir FALSE ou NULL, a palavra-chave ELSIF introduzir condies adicionais.) uma palavra-chave que se for atingida pelo controle, executar a seqncia de instrues que segue a palavra-chave

Exemplo 9: Definir o ID do gerente como 22 se o nome do funcionrio for OSBORNE ... IF v_ename = 'OSBORNE' THEN v_mgr := 22; END IF; ... Exemplo 10: Definir o cargo como Salesman, o nmero do departamento como 35 e a comissao com o valor de 20% do salrio atual se o nome for MILLER. ... IF v_ename = MILLER THEN v_job := SALESMAN; v_deptno := 35; v_valor_com := sal * 0,20; END IF; ... Exemplo 11: Definir o cargo para Manager se o nome do funcionrio for King. Se o nome do funcionrio for diferente de King, defina o cargo para Clerk. ... IF v_ename = KING THEN v_job := MANAGER; ELSE v_job := CLERK; END IF; ... Exemplo 12: Dado um valor qualquer, representado pela varivel v_valor, calcule um percentual deste valor, de acordo com as condies estabelecidas, e armazene em v_perc_valor.

Se o valor for maior do que 100, 100% Se o valor for maior do que 50 e menor ou igual a 100, 50% Para os demais valores 10% ... IF

v_valor > 100 THEN v_perc_valor := 2 * v_start; ELSIF v_valor >= 50 THEN v_perc_valor := .5 * v_start; ELSE v_perc_valor := .1 * v_start; END IF; ...

ATENO: permitida qualquer quantidade de clusulas ELSIF, mas pode haver no mximo uma clusula ELSE. 1.2.2. Estruturas de repetio (Loop) Em determinadas situaes temos que repetir o programa ou parte dele inmeras vezes. Reiniciar o programa para cada repetio no uma soluo muito prtica, e algumas vezes invivel. Uma soluo comum a utilizao de estruturas de repetio. Segundo Puga i o conceito de repetio (ou looping) utilizado quando se deseja repetir certo trecho de instrues por um nmero de vezes. O nmero de repeties pode ser conhecido anteriormente ou no, mas necessariamente precisa ser finito. Nem todas as estruturas de repetio possuem recursos para fazer a contagem do nmero de vezes que o lao dever ser repetido, por isso, deve-se utilizar uma varivel de apoio sempre do tipo inteiro. O PL/SQL oferece diversos recursos para estruturar laos de repetio: Loop bsico para fornecer aes repetitivas sem condies gerais Loops FOR para fornecer controle iterativo para aes com base em uma contagem Loops WHILE para fornecer controle iterativo para aes com base em uma condio

ATENO: Instruo EXIT para termina o lao de repetio 1.2.2.1 Loop Bsico Um loop bsico permite a execuo de sua instruo pelo menos uma vez, entretanto, se a condio exit for colocada no incio do loop, antes de qualquer outra instruo executvel, e ela for verdadeira, ocorrer a sada do loop e as instrues jamais sero executadas. Sem a instruo EXIT, o loop seria infinito! Sintaxe: LOOP conjunto de instrues; EXIT [WHEN condio]; END LOOP; delimitador de incio do lao instrues a serem executadas em cada iterao condio para sada do lao delimitador de fim do lao

Pode-se emitir EXIT como uma ao dentro de uma instruo IF ou como uma instruo independente dentro do loop. Quando a instruo EXIT encontrada, a condio na clusula WHEN avaliada, se a condio produzir TRUE, o loop finalizar e o controle passar para a prxima instruo aps o loop. Um loop bsico pode conter vrias instrues EXIT..

Exemplo 13: Inserir os 10 primeiros novos itens de linha para o nmero do pedido 601. DECLARE v_ordid item.ordid%TYPE := 601; v_counter NUMBER(2) := 1; BEGIN LOOP INSERT INTO item (ordid, itemid) VALUES (v_ordid, v_counter); v_counter := v_counter + 1; EXIT WHEN v_counter > 10; END LOOP; END; 1.2.2.2 Loop FOR Os loops FOR, realizam as iteraes de acordo com a instruo de controle que precede a palavra-chave LOOP. Sintaxe: FOR contador in [REVERSE] limite_inferior..limite_superior LOOP conjunto de instrues; ... END LOOP; onde, Contador

REVERSE limite_inferior limite_superior

um inteiro declarado implicitamente cujo valor aumenta ou diminui automaticamente (diminuir se a palavra-chave REVERSE for usada) em 1 a cada iterao do loop at o limite superior ou inferior a ser alcanado faz o contador decrescer a cada iterao a partir do limite superior at o imite inferior. (Note que o limite inferior ainda referenciado primeiro.) especifica o limite inferior da faixa de valores do contador especifica o limite superior da faixa de valores do contador

ATENO: A seqncia de instrues executada sempre que o contador incrementado, conforme determinado pelos dois limites. Os limites superiores e inferiores da faixa do loop podem ser literais, variveis ou expresses, mas devem ser avaliados para inteiros. Se o limite inferior da faixa do loop for avaliado para um inteiro maior do que o limite superior, a seqncia de instrues no ser executada. Exemplo 14: Inserir os 10 primeiros novos itens de linha para o nmero do pedido 601. DECLARE v_ordid item.ordid%TYPE := 601; BEGIN FOR i IN 1..10 LOOP INSERT INTO item(ordid, itemid) VALUES(v_ordid, i); END LOOP; END; 1.2.2.3 Loop WHILE Pode-se usar o loop WHILE para repetir uma seqncia de instrues at que a condio para controle no seja mais verdadeira, a condio avaliada ao incio de cada iterao, sendo assim, se a condio for falsa no incio do loop, nenhuma iterao futura ser executada.

Sintaxe: WHILE condio LOOP conjunto de instrues; ... END LOOP; Onde, condio instruo

uma expresso ou varivel Booleana (TRUE, FALSE, ou NULL) pode ser uma ou mais instrues SQL ou PL/SQL

ATENO: Se as variveis envolvidas nas condies no se alterarem no curso do corpo do loop, a condio permanecer TRUE e o loop no terminar. Se a condio produzir NULL, o loop ser ignorado e o controle passar para a prxima instruo.

Exemplo 15: Solicitar o nmero de iteraes do lao e exibir o valor da varivel de controle a cada iterao. ACCEPT p_no_voltas PROMPT 'Digitar o nmero de voltas do lao: ' DECLARE v_count NUMBER(2) := 1; BEGIN WHILE v_count <= &p_no_voltas LOOP DBMS_OUTPUT.PUT_LINE(Valor do contador... || v_count); v_count := v_count + 1; END LOOP; END; / 1.2.3. Loops e Labels Aninhados Pode-se aninhar loops para vrios nveis. Voc pode aninhar loops bsicos, FOR e WHILE um dentro do outro. A terminao de um loop aninhado no terminar o loop delimitado a menos que seja criada uma exceo. Entretanto, pode-se colocar labels em loops e sair do loop externo com a instruo EXIT. Os nomes de labels seguem as mesmas regras de outros identificadores. Um label colocado antes de uma instruo, seja na mesma linha ou em uma linha separada. Colocar o label no loop antes da palavra LOOP dentro dos delimitadores de label (<<label>>). Se for atribudo um label ao loop, o nome do label poder ser opcionalmente includo aps a instruo END LOOP para clareza. No exemplo a seguir, existem dois loops. O loop externo identificado pelo label, <<Loop_externo>> e o loop interno identificado pelo label <<Loop_interno>>. O loop interno est aninhado dentro do Loop externo. Os nomes de label so includos aps a instruo END LOOP para clareza. Exemplo 16: Demonstrao do uso de labels. ... BEGIN <<loop_externo>> LOOP v_counter := v_counter+1; EXIT WHEN v_counter>10; <<loop_interno>> LOOP ...

EXIT Outer_loop WHEN total_done = 'YES'; -- Abandona ambos os Loops EXIT WHEN inner_done = 'YES'; -- Abandona somente o Loop interno ... END LOOP loop_interno; ... END LOOP loop_externo; END; . . . 1.3. Cursores Para processar uma instruo de SQL o Oracle atribui uma rea de memria denominada rea de contexto. A rea de contexto contm o nmero de linhas processadas, um apontador e, para consultas, o conjunto ativo. O conjunto ativo o conjunto de linhas recuperadas uma consulta, por exemplo: A consulta select * from EMPR ter como conjunto ativo todas as linhas e colunas da tabela EMPR; Na consulta select EMPR_NOME_DS, EMPR_SERV_DS from EMPR where DEPT_NUME_NR = 20, o conjunto ativo ser composto pelas linhas e colunas que atendem condio.

O cursor o apontador da rea de contexto. Existem dois tipos de cursores os cursores: Implcitos: no declarado e realizado implicitamente quando as instrues DML e PL/SQL select ..into so realizadas. Processam apenas uma linha. Se uma consulta retornar mais do que uma linha um erro ser gerado. Explcitos: precisam ser declarados explicitamente na rea declarativa do bloco PL/SQL. Pode processar vrias linhas; por meio de um cursor explcito possvel, em um bloco PL/SQL, controlar a rea de contexto e os processamentos que nela ocorrem

ATENO: Todos os exemplos de blocos PL/SQL, apresentados at este ponto e que continham instrues DML so exemplos de cursores implcitos. Os atributos de cursores podem ser utilizados em cursores implcitos ou explcitos. Estes atributos permitem a realizao de testes nos resultados das instrues SQL, so eles: %FOUND: retorna verdadeiro caso alguma linha (tupla) tenha sido afetada %NOTFOUND: retorna verdadeiro caso no tenha encontrado nenhuma tupla. Seu valor falso at a ltima tupla. %ISOPEN: indica se o cursor est aberto ou no. %ROWCOUNT: retorna o nmero de tuplas do cursor.

Exemplo 17: Deletar linhas que especificaram um nmero de ordem de compra a partir da tabela ITEM. Exibir o nmero de linhas deletadas. VARIABLE linhas_deletadas VARCHAR2(30) DECLARE v_deptno NUMBER := 10; BEGIN DELETE FROM EMPR WHERE DEPT_NUME_NR = v_deptno; :linhas_deletadas := (SQL%ROWCOUNT || ' linhas deletadas.'); END; /

PRINT linhas_deletadas O exemplo 17 um cursor implcito, o atributo SQL%ROWCOUNT est sendo utilizado para possibilitar a exibio do nmero de linhas deletadas. 1.3.1. Cursores Explcitos O Oracle Server usa reas de trabalho chamadas reas SQL particulares para executar instrues SQL e para armazenar informaes de processamento. Pode-se usar cursores do PL/SQL para nomear uma rea SQL particular e acessar suas informaes armazenadas. Os cursores explcitos podem ser utilizados para processar individualmente cada linha retornada por uma instruo SELECT de vrias linhas. O cursor orienta todas as fases do processamento. Conjunto Ativo
7369 7566 SMITH JONES SCOTT ADAMS FORD CLERK MANAGER ANALYST CLERK ANALYST

cursor

7788 7876 7902

Linha atual

O conjunto de linhas retornado por uma consulta de vrias linhas chamado conjunto ativo. Seu tamanho correspondente ao nmero de linhas que atende aos critrios da pesquisa. A figura anterior mostra como um cursor explcito "aponta" para a linha atual do conjunto ativo. Isso permite que o programa processe as linhas uma de cada vez. Um programa PL/SQL abre um cursor, processa linhas retornadas por uma consulta e, em seguida, fecha o cursor. O cursor marca a posio atual no conjunto ativo. A seqncia para execuo do controle dos cursores consiste em: Abertura Recuperao Verificao das do Linhas trmino Fechamento

Declarao

1. 2.

3.

4.

Declare o cursor nomeando-o e definindo a estrutura da consulta a ser executada dentro dele. Abra o cursor. A instruo OPEN executa a consulta e vincula as variveis que estiverem referenciadas. As linhas identificadas pela consulta so chamadas conjunto ativo e esto agora disponveis para extrao. Extraia dados do cursor. No diagrama de fluxo mostrado no slide, aps cada extrao voc testa o cursor para qualquer linha existente. Se no existirem mais linhas para serem processadas, voc precisar fechar o cursor. Feche o cursor. A instruo CLOSE libera o conjunto ativo de linhas. Agora possvel reabrir o cursor e estabelecer um novo conjunto ativo.

1.3.1.1 Declarao de cursores explcitos Os cursores explcitos devem ser declarados no bloco PL/SQL e a manipulao do seu conjunto ativo deve ser realizada na rea de processamento do bloco. Sintaxe: CURSOR nome_cursor IS consulta; Onde, CURSOR a instruo utilizada para declarar um cursor explcito.

nome_cursor consulta

um identificador para o cursor uma instruo SELECT

ATENO: No se deve incluir a clusula INTO na declarao de cursor porque ela aparecer posteriormente na instruo FETCH. Pode-se fazer referncia a variveis dentro da consulta, mas elas devem ser declaradas antes da instruo CURSOR. Exemplo 18: Declarar cursores para recuperar o cdigo e o nome de todos os funcionrios e para recuperar todas as colunas da tabela dept quando o cdigo do departamento for igual a 10. DECLARE CURSOR EMPR_cursor IS SELECT EMPRno, EMPR_NOME_DS FROM EMPR; CURSOR dept_cursor IS SELECT * FROM dept WHERE deptno = 10; BEGIN ... 1.3.1.2 Abertura do Cursor A instruo OPEN abre o cursor para executar a consulta e identificar o conjunto ativo, que consiste em todas as linhas que atendem aos critrios de pesquisa da consulta. O cursor aponta agora para a primeira linha do conjunto ativo. Sintaxe: OPEN nome_cursor; OPEN uma instruo executvel que realiza as seguintes operaes: 1) Aloca memria dinamicamente para uma rea de contexto que finalmente conter informaes cruciais de processamento. 2) Analisa a instruo SELECT. 3) Vincula as variveis de entrada isto , define o valor das variveis de entrada obtendo seus endereos de memria. 4) Identifica o conjunto ativo isto , o conjunto de linhas que satisfaz os critrios de pesquisa. As linhas no conjunto ativo no so recuperadas para variveis quando a instruo OPEN executada. Em vez disso, a instruo FETCH recupera as linhas. 5) Posiciona o indicador imediatamente antes da primeira linha no conjunto ativo. ATENO: Se a consulta no retornar qualquer linha quando o cursor for aberto, o PL/SQL no criar uma exceo , pode-se testar o status do cursor aps a extrao. 1.3.1.3 Recuperao das linhas do Cursor A instruo FETCH recupera as linhas no conjunto ativo uma de cada vez. Aps cada extrao, o cursor avana para a prxima linha no conjunto ativo. Sintaxe: FETCH cursor_name INTO [varivel1, varivel2, ...|record_name];

onde, cursor_name varivel record_name o nome do cursor declarado anteriormente uma varivel de sada para armazenar os resultados, o nmero de variveis deve ser compatvel com o nmero de colunas da consulta. o nome do registro em que os dados recuperados so armazenados (A varivel de registro pode ser declarada usando o atributo %ROWTYPE.)

A instruo FETCH realiza as seguintes operaes: 1) Avana o indicador para a prxima linha no conjunto ativo. 2) L os dados da linha atual para as variveis PL/SQL de sada. Deve-se incluir o mesmo nmero de variveis na clusula INTO da instruo FETCH do que as colunas na instruo SELECT, as variveis devem ser do mesmo tipo de dado da coluna correspondente. Como alternativa, pode ser definido um registro para o cursor e faa referncia do registro na clusula FETCH INTO. Verificar se o cursor possui linhas. Se uma extrao no obtiver valores, no existem linhas remanescentes para serem processadas no conjunto ativo e nenhum erro ser registrado. 1.3.1.4 Fechamento de Cursor A instruo CLOSE desativa o cursor e o conjunto ativo se torna indefinido. O cursor deve ser fechado aps completar o processamento da instruo SELECT. Essa etapa permite que o cursor seja reaberto, se necessrio. Assim, pode-se estabelecer um conjunto ativo diversas vezes; A rea de contexto liberada. Sintaxe: CLOSE nome_cursor; Embora seja possvel terminar o bloco PL/SQL sem fechar cursores, deve-se criar o hbito de fechar qualquer cursor declarado explicitamente para liberar recursos. Existe um limite mximo para o nmero de cursores abertos por usurio, que determinado pelo parmetro OPEN_CURSORS no campo de parmetros do banco de dados. OPEN_CURSORS = 50 por default. Exemplo 19: Criar um bloco PL/SQL no qual seja calculado o salrio anual de cada funcionrio e armazene na tabela sal_tot o nome do funcionrio e o seu salrio anual. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ACCEPT p_cargo_func PROMPT 'Digite o CARGO do funcionrio ' VARIABLE g_n_ocorrencias NUMBER; DECLARE v_cargo_func EMPR_SERV_DS%TYPE := '&p_cargo_func'; v_nome_func EMPR_NOME_DS%TYPE; v_sal_mes EMPR_SALA_VL%TYPE; v_sal_ano number(9,2); CURSOR sal_func_cursor IS SELECT EMPR_NOME_DS, EMPR_SALA_VL, EMPR_SALA_VL * 12 FROM EMPR WHERE EMPR_SERV_DS = v_cargo_func; BEGIN OPEN sal_func_cursor; LOOP FETCH sal_func_cursor INTO v_nome_func, v_sal_mes, v_sal_ano; EXIT WHEN sal_func_cursor%NOTFOUND; INSERT INTO sal_tot VALUES(v_nome_func, v_sal_ano); END LOOP;

19 20 21 22 23

:g_n_ocorrencias := sal_func_cursor%ROWCOUNT; CLOSE sal_func_cursor; END; / PRINT g_n_ocorrencias

Sobre o exemplo: As linhas do exemplo 19 foram enumeradas para facilitar a explicao sobre o cdigo. Na linha 8 est sendo iniciada a declarao do cursor sal_func_cursor, observe que na linha 11, na condio para recuperao das linhas do cursor, utilizada a varivel v_cargo_func que foi declarada anteriormente na linha 4. Na linha 13 o cursor aberto. Na linha 14 iniciado o lao de repetio que ser encerrado quando no existirem mais linhas no conjunto ativo para serem percorridas (linha 16) Na linha 15 a instruo fetch recupera a linha corrente do conjunto ativo e armazena os dados das colunas nas variveis v_nome_func, v_sal_mes, v_sal_ano Na linha 17 os valores recuperados so inseridos na tabela sal_tot. Na linha 20 o cursor fechado. 1.3.2. Cursores de Atualizao Os registros retornados pela consulta que est associada a um cursor podem ser lidos, alterados ou excludos. Os cursores que permitem este tipo de operao so chamados cursores de atualizao e devem ser declarados da seguinte maneira: cursor nome_cursor is select ... from ... (consulta) for update [of nome_coluna] [nowait]; Veja o exemplo de um cursor para atualizao e a seguir as explicaes do cdigo e das clusulas da sintaxe: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Declare cursor cursor_ex_atual Is select EMPR_NOME_DS, EMPR_SERV_DS, sal from EMPR for update of sal nowait; Begin for reg_ex_atual in cursor_ex_atual loop if reg_ex_atual.job = CLERK then update EMPR set sal = sal * 1.10 where current of cursor_ex_atual; elseif reg_ex_atual.job = PRESIDENT then update EMPR set sal = sal + sal where current of cursor_ex_atual; Else delete from EMPR where current of cursor_ex_atual; end loop;

Sobre o cdigo: A clusula for update, utilizada na linha 6, deve ser a ltima instruo da declarao de um cursor e indica que os registros retornados pelo cursor podero ser atualizados (alterados ou excludos)

of sal, linha 6, indica a coluna ou lista de colunas de referncia para consulta, neste caso sal a coluna que ser atualizada. Est expresso opcional. A clusula nowait, linha 6, deve ser utilizada para gerar uma exceo tratvel caso a tabela esteja bloqueada por outro usurio, isto , ser emitida uma mensagem informando que a tabela a ser utilizada est bloqueada por outro usurio. Est clusula opcional, no entanto, se for omitida o cursor de atualizao ficar por tempo indeterminado esperando o desbloqueio da tabela para que prossiga com a consulta. A varivel reg_ex_atual, declarada implicitamente como cursor_ex_atual%rowtype, (na linha 8), isto , est varivel do tipo registro e possui os mesmos campos utilizados na consulta associada ao cursor. Isso ocorre toda vez que a instruo for utilizada para controlar a leitura dos registros retornados pela consulta em questo. Para referenciar um campo deve-se colocar o nome da varivel . (ponto) e o nome do campo, por exemplo: reg_ex_atual.job est sendo referenciado o campo EMPR_SERV_DS da tabela EMPR. A instruo where current of nome_cursor, linhas 11, 14 e 17, indica que a operao de atualizao ou excluso ser realizada no registro corrente, isto , no registro que est sendo apontado pelo cursor naquele momento.

1.3.3. Variveis de Cursores Os cursores vistos at ento, so estticos, isto , o cursor associado a uma instruo SQL que em tempo de compilao retorna os registros associados quela consulta. As variveis de cursor podem ser utilizadas para receber valores em tempo de execuo possibilitando que diferentes resultados sejam obtidos a partir de um nico cursor. As variveis de cursor so do tipo referncia e devem ser declarados da seguinte maneira: TYPE nome_tipo IS REF CURSOR RETURN tipo_retorno; onde, nome_tipo o nome do tipo de referncia o tipo de retorno tem que ser do tipo registro Variveis do tipo referncia (REF) so como apontadores, isto , apontam para diferentes reas de memria ao longo da utilizao do programa, so diferentes das variveis comuns que so utilizadas para identificar uma rea de memria. Variveis do tipo registro podem ser declaradas utilizando %ROWTYPE Exemplos de declaraes de variveis de cursor: Exemplo 1 TYPE t_registro IS RECORD ( nome EMP.EMPR_NOME_DS%type, EMPR_SERV_DS%type); v_registro t_registro; TYPE t_referencia IS REF CURSOR RETURN t_registro; cargo

sobre o exemplo: est sendo declarada o tipo t_registro, do tipo registro. Este registro ser composto pelos campos nome e cargo que possuem respectivamente o formato do campo EMPR_NOME_DS da tabela EMPR e EMPR_SERV_DS da mesma tabela. est sendo declarada a varivel v_registro que ser do tipo t_registro, tipo construido na declarao anterior est sendo declarado o tipo referncia t_referencia para o cursor, que ter como retorno o valor de t_registro. Exemplo 2- usando %ROWTYPE: TYPE t_AlunoRef IS REF CURSOR RETURN aluno%ROWTYPE;

Para abrir uma varivel de cursor para consulta OPEN varivel_cursor FOR consulta_pretendida Exemplo: DECLARE TYPE t_AlunoRef IS REF CURSOR RETURN aluno%ROWTYPE; v_aluno t_alunoRef; ... BEGIN ... OPEN v_aluno FOR SELECT nome, curso from ALUNO; ... ATENO: O retorno do cursor deve ser compatvel com o retorno da consulta, caso contrrio ocorrer um erro. 1.4. Tratamento de Excees Uma exceo uma ocorrncia no esperada, ou diferente daquela programada para ser executada. Em outras palavras uma exceo um erro! Por exemplo: O usurio digita um caractere para uma varivel do tipo numrico, neste exemplo temos uma entrada de dados diferente da esperada; um cursor declarado com um retorno que espera um conjunto de campos diferentes daqueles que so solicitados pela consulta; Os erros podem ocorrer durante a compilao ou durante a execuo do programa. Os erros de compilao esto associados a sintaxe das instrues: nome dos comandos, declarao das variveis, organizao dos comandos, entre outros. Neste tipo de erro o compilador da linguagem informa ao programador durante a tentativa de executar uma instruo a ocorrncia do erro: Exemplo: SQL> selet * from EMPR; SP2-0734: incio de comando desconhecido "selet * fr..." - restante da linha ignorado. Os erros de execuo (runtime) esto associados utilizao do programa, neste caso quando as excees no so previstas e tratadas, o erro gerado por elas interrompe o processamento e uma mensagem devolvida para a aplicao. Exemplo: Ao executar o programa zero.sql, ser gerado um erro pela tentativa de dividir um valor por zero declare x number := 0; y number := 5; resultado number; begin resultado := y / x; ... end; Compilando o programa: SQL> @zero.sql declare *

ERRO na linha 1: ORA-01476: o divisor igual a zero ORA-06512: em line 6 Para realizao da operao aritmtica de diviso, o divisor dever ser diferente de 0. No existe erro de sintaxe, mas, o valor esperado para divisor no est adequado, fazendo com que o programa no funcione, ento, temos uma exceo! Para resolver este problema algumas linguagens de programao oferecem recursos para tratamento de excees. O tratamento de uma exceo consiste em identificar um erro em tempo de execuo e trat-lo de maneira que o usurio seja informado sobre o que est acontecendo e o programa no seja interrompido bruscamente. O Oracle possui alguma excees pr-definidas, mas o desenvolvedor tambm pode definir excees personalizadas. O bloco PL/SQL com tratamento de excees tem a seguinte estrutura: DECLARE nome_exceo exception; /* declarao da exceo BEGIN RAISE exceo; /* abertura da exceo EXCEPTION /* rea de tratamento das excees WHEN nome_exceo THEN instrues para tratamento da exceo; WHEN OTHERS THEN instrues para tratamento da exceo; END; 1.4.1. Excees pr-definidas nomeadas Para alguns erros comuns, existem pr-definies de excees, no havendo, neste caso, a necessidade de serem declaradas para serem utilizadas. Exemplo 1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ACCEPT p_nome PROMPT Digite o nome do funcionrio ... DECLARE v_nome EMP.EMPR_NOME_DS%type := &p_nome; BEGIN SELECT EMPR_NOME_DS, sal FROM EMPR WHERE EMPR_SERV_DS = 'CLERK' and EMPR_NOME_DS = v_nome; EXCEPTION when NO_DATA_FOUND then DBMS_OUTPUT.PUT_LINE('Nenhum registro foi encontrado'); when TOO_MANY_ROWS then DBMS_OUTPUT.PUT_LINE('Muitos funcionrios possuem este cargo'); when OTHERS then DBMS_OUTPUT.PUT_LINE('ERRO DESCONHECIDO ' ); END;

Neste exemplo, est sendo realizada uma consulta (linha 5), como esta consulta no est associada a um cursor explcito, dever retornar apenas um registro, caso contrrio uma exceo ser gerada, isto ocorre pois no est sendo reservada uma rea para armazenamento destas informaes e nem tampouco os dados retornados esto associados variveis ou existe uma estrutura de repetio. Se nenhuma linha for retornada tambm ser gerada uma exceo. Estas duas excees so pr definidas pelo Oracle como NO_DATA_FOUND (linha 9) e TOO_MANY_ROWS (linha 11).

A seo de tratamento de exceo captura somente as excees especificadas; quaisquer outras excees no sero capturadas exceto se for utilizado o handler de exceo OTHERS. Esse handler captura qualquer exceo que ainda no esteja tratada. Por essa razo, OTHERS o ltimo handler de exceo definido. No exemplo, na clusula OTHERS (linha 13), se ocorrer qualquer outra exceo, diferente de NO_DATA_FOUND e TOO_MANY_ROWS ser exibida a mensagem 'ERRO DESCONHECIDO '. ATENO: Podem ser definidos vrios handlers de exceo para o bloco, cada um deles com o seu prprio conjunto de aes. Quando ocorre uma exceo, o cdigo PL/SQL processa somente um handler antes de sair do bloco. As excees no podem aparecer em instrues de atribuio ou instrues SQL. Funes para Captura de Erro Quando ocorre uma exceo, pode-se identificar o cdigo ou a mensagem de erro associado usando duas funes SQLCODE e SQLERRM. Com base nos valores do cdigo ou mensagem, voc pode decidir qual ao subseqente tomar com base no erro. SQLERRM Funo numrica que devolve o cdigo do erro; SQLCODE Funo caractere que devolve o texto da mensagem do erro. Quando uma exceo capturada no handler de exceo WHEN OTHERS, pode-se usar um conjunto de funes genricas para identificar esses erros. No exemplo a seguir os valores de SQLCODE e SQLERRM esto sendo atribudos a variveis e, em seguida, essas variveis sendo usadas em uma instruo SQL. Exemplo: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 DECLARE v_error_code NUMBER; v_error_message VARCHAR2(255); BEGIN ... EXCEPTION ... WHEN OTHERS THEN ROLLBACK; v_error_code := SQLCODE ; v_error_message := SQLERRM ; INSERT INTO errors VALUES(v_error_code, v_error_message); END;

ATENO: Trunque o valor de SQLERRM para um tamanho conhecido antes de tentar grav-lo para uma varivel. 1.4.2. Excees nomeadas pelo desenvolvedor e associadas a cdigos de erro : Devem ser declaradas explicitamente na seo de declaraes e abertas na rea de processamento quanto houver a possibilidade de erro: Exemplo: set verify on accept p_deptno prompt ' insira o numero do departamento ' accept p_local prompt ' insira a localizaao do depto ' DECLARE e_depto_invalido EXCEPTION;

v_deptno dept.deptno%type := &p_deptno; BEGIN Update dept set loc = '&p_local' where deptno = v_deptno; IF sql%notfound then Raise e_depto_invalido; end if; commit; EXCEPTION when e_depto_invalido then dbms_output.put_line('departamento ' || to_char(v_deptno) || ' nao cadastrado'); END; onde: e_depto_invalido EXCEPTION; e_depto_invalido

0 1 2 3 4 5 6 7

(linha 5) est sendo declarada a exceo

caso a instruo para atualizao da tabela no encontre registros para efetuar a transao, bloco de seleo IF (linha 11) abre a exceo e_depto invlido ento o fluxo do programa desviado para a rea de tratamento de excees.

Algumas excees declaradas pelo usurio podem ser associadas a erros Oracle pr-definidos, mas no nomeados. Podemos associar estas excees a um nome da seguinte maneira: PRAGMA EXCEPTION_INIT (nome_exceo, cdigo_Oracle_erro); onde, nome_exceo deve ser declarada na rea declarativa codigo_Oracle_erro deve-se associar a exceo declarada ao nmero de erro padro Na rea de excees deve-se fazer referncia exceo declarada dentro da rotina de tratamento de exceo correspondente. O PRAGMA EXCEPTION_INIT uma diretiva de compilao que informa o compilador para associar um nome de exceo a um nmero de erro do Oracle. Isso permite que possa ser consultada qualquer exceo interna por nome e criado um handler especfico para ela. ATENO: PRAGMA (tambm chamado pseudo-instrues) uma palavra-chave que significa que a instruo uma diretiva de compilador, que no processada ao executar o bloco PL/SQL. Ao invs disso, orienta o compilador do PL/SQL para interpretar todas as ocorrncias do nome da exceo dentro do bloco como o nmero de erro do Oracle Server associado. Exemplo: Capturar por nmero de erro do Oracle Server 2292, uma violao de restrio de integridade. Se um determinado usurio tentar remover um departamento, para o qual existam funcionrios, imprima uma mensagem informando que esse departamento no pode ser removido. 1 2 3 4 5 6 7 8 9 DECLARE e_emps_remaining EXCEPTION; PRAGMA EXCEPTION_INIT ( e_emps_remaining, -2292); v_deptno dept.deptno%TYPE := &p_deptno; BEGIN DELETE FROM dept WHERE deptno = v_deptno; COMMIT; EXCEPTION

10 11 12

WHEN e_emps_remaining THEN DBMS_OUTPUT.PUT_LINE (No possvel remover o departamento || TO_CHAR(v_deptno) || '. Existem funcionrios. '); END;

Na linha 2 est sendo declarada a exceo e_emps_remaining. Na linha 3 a exceo declarada est sendo associada ao erro oracle 2292. Excees declaradas e definidas pelo desenvolvedor O PL/SQL permite que voc defina suas prprias excees. As excees PL/SQL definidas pelo usurio devem ser: Declaradas na seo de declarao de um bloco PL/SQL Criadas explicitamente com instrues RAISE Exemplo: Esse bloco atualiza a descrio de um produto. O usurio fornece o nmero do produto e a nova descrio. Se o usurio incluir um nmero de produto inexistente, nenhuma linha ser atualizada na tabela PRODUCT. Crie uma exceo e imprima uma mensagem para o usurio alertando-os de que foi includo um nmero de produto invlido. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 DECLARE e_invalid_product EXCEPTION; BEGIN UPDATE product SET descrip = '&product_description' WHERE prodid = &product_number; IF SQL%NOTFOUND THEN RAISE e_invalid_product; END IF; COMMIT; EXCEPTION WHEN e_invalid_product THEN DBMS_OUTPUT.PUT_LINE('Invalid product number.'); END;

Na linha 2 a exceo est sendo declarada; Na linha 8 est sendo criada explicitamente; e Na linha 12 est sendo tratada. Procedimento RAISE_APPLICATION_ERROR O procedimento RAISE_APPLICATION_ERROR utilizado para comunicar uma exceo predefinida interativamente retornando um cdigo ou uma mensagem de erro no padronizada. Com RAISE_APPLICATION_ERROR possvel relatar erros para a aplicao e evitar o retorno de excees no tratveis. Sintaxe:
RAISE_APPLICATION_ERROR

(numero_erro, mensagem[, {TRUE | FALSE}]);

Onde: nmero_erro um nmero especificado pelo usurio para a exceo entre 20000 e 20999. mensagem a mensagem especificada pelo usurio para a exceo. Trata-se de uma string de caracteres com at 2.048 bytes. TRUE | FALSE um parmetro Booleano opcional (Se TRUE, o erro ser colocado na pilha de erros anteriores. Se FALSE, o default, o erro substituir todos os erros anteriores.) O procedimento RAISE_APPLICATION_ERROR pode ser usado em dois locais diferentes: Na seo de exceo

Na seo executvel Exemplo 1 : Utilizando na seo de excees ... EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR (-20201, 'Manager is not a valid EMPRloyee.'); END; Exemplo 2 : Utilizando na seo de executvel ... BEGIN ... DELETE FROM EMPR WHERE mgr = v_mgr; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR(-20202,'This is not a valid manager'); END IF; ... Propagando uma Exceo para um Sub-bloco Ao invs de se capturar uma exceo dentro do bloco PL/SQL, possvel propagar a exceo para permitir que ela seja tratada pelo ambiente de chamada. Cada ambiente de chamada tem seu prprio modo de exibir e acessar erros. Exemplo: DECLARE . . . e_no_rows exception; e_integrity exception; PRAGMA EXCEPTION_INIT (e_integrity, -2292); BEGIN FOR c_record IN EMPR_cursor LOOP BEGIN SELECT ... UPDATE ... IF SQL%NOTFOUND THEN RAISE e_no_rows; END IF; EXCEPTION WHEN e_integrity THEN ... WHEN e_no_rows THEN ... END; END LOOP; EXCEPTION WHEN NO_DATA_FOUND THEN . . . WHEN TOO_MANY_ROWS THEN . . . END; Quando um sub-bloco trata uma exceo, ele termina normalmente e o controle retorna ao bloco delimitado imediatamente aps a instruo END do sub-bloco. Entretanto, se o cdigo PL/SQL criar uma exceo e o bloco atual no tiver um handler para essa exceo, a exceo propagar em blocos delimitados sucessivos at localizar um handler. Se nenhum desses blocos tratar a exceo, o resultado ser uma exceo no tratvel no ambiente de host (chamador).

Quando a exceo propaga para um bloco delimitado, as aes executveis restantes desse bloco so ignoradas. Uma vantagem desse comportamento que pode-se delimitar instrues que exigem seus prprios tratamentos de erro exclusivos em seu prprio bloco, enquanto deixa o tratamento de exceo mais geral para o bloco delimitado. 1.5. Procedimentos Um procedimento um conjunto de instrues que realiza determinada tarefa. (Puga[2003]). A definio e o funcionamento dos procedimentos similar programao em outras linguagens e envolve basicamente os passos de Ento, O cdigo fonte armazenado no dicionrio de dados 1 O procedimento compilado o se a compilao for bem sucedida o P-code armazenado no dicionrio de dados e no pode ser consultado o se ocorrerem erros de compilao, estes sero armazenados no USER_ERRORS identificao do procedimento definio dos parmetros ou parmetro conjunto de instrues do procedimento submisso do cdigo ao SGBDR

Sintaxe: CREATE [ OR REPLACE] nome_procedimento [parmetro [{in, out, in out}] tipo_parmetro, ... {IS ou AS} BEGIN corpo_do_procedimento END [nome_procedimento]; onde: instruo para criao ou substituio do procedimento nome_procedimento nome que ser dado ao procedimento parmetro [parmetro [{in, out, in nome do parmetro que poder ser para entrada, saout}] da ou entrada e sada tipo_parmetro tipo de dado que o parmetro poder aceitar, os parmetros podem ser IN, OUT ou IN OUT IS ou AS tem a mesma funo e indicam o bloco que estar associado ao procedimento, substitui a palavra reservada DECLARE. BEGIN corpo_do_procedimento END Respectivamente o incio do bloco, o conjunto de instrues do procedimento e o final do bloco. Create or replace

Pode-se consultar a USER_SOURCE

1.5.1. Utilizando parmetros 2 de entrada Os parmetros so por default do tipo IN, isto , so utilizados para entrada de valores que sero utilizados internamente pelo procedimento. A procedure reajuste recebe os parmetros v_cdigo e v_porcentagem cujos valores sero utilizados para alterao de um registro na tabela EMPR. CREATE OR REPLACE PROCEDURE reajuste (v_codigo_emp IN EMPR_NUME_NR%type, v_porcentagem IN number) IS BEGIN UPDATE EMPR SET sal = sal + (sal *( v_porcentagem / 100 ) ) where EMPRno = v_codigo_emp; COMMIT; END reajuste; / Os parmetros IN podem receber valores default: v_porcentagem IN number default 25. ATENO: Somente os parmetros IN podem ser atribudos de valores default, os parmetros OUT e IN OUT no podem. 1.5.2. Utilizando parmetros de sada Os parmetros do tipo OUT so utilizados para sada de valores processados para o ambiente de chamada. A procedure consulta_emp recebe o parmetro de entrada p_id, que ser utilizado na condio da consulta para recuperar o registro de um dado funcionrio. O parmetro de sada p_salrio ser utilizado para devolver o valor, resultado de uma operao interna da procedure, para a rotina chamadora. (no item 1.1.5 ser exemplificada a utilizao das procedures) CREATE OR REPLACE PROCEDURE consulta_emp (p_id in EMPR_NUME_NR%type, p_nome out EMP.EMPR_NOME_DS%type, p_salario out EMPR.sal%type) IS BEGIN select EMPR_NOME_DS, sal into p_nome, p_salario from EMPR where EMPRno = p_id; END consulta_emp; /

Parmetro um valor, constante ou varivel, que passado de uma rotina chamadora para uma rotina executora, onde a rotina chamadora um algoritmo que usa as funcionalidades da rotina executora, por exemplo:

Parmetro formal variveis da rotina executora que recebem os valores da rotina chamadora, isto , recebem os parmetros reais.
ATENO: As variveis dos parmetros formais no devem ter tamanho ou preciso pr determinados. Parmetro real valores (constantes ou reais) que so passados da rotina chamadora para a rotina executora.

1.5.3. Utilizando parmetros de entrada e sada Os parmetros IN OUT so utilizados para entrada de valores, que podero ser processados, o parmetro poder ser alterado e o seu valor pode ser devolvido para o ambiente de chamada. A procedure formata_fone recebe o parmetro p_fone, que representa uma cadeia de caracteres. Este parmetro recebe de o resultado das operaes da procedure e devolte este valor a rotina chamadora. Sendo assim um parmetro de entrada quando passa para a procedure o valor que ser utilizado no processamento, um parmetro de sada quando recebe o resultado do processamento, portanto, tem o seu valor alterado, e devolve o resultado rotina chamadora. CREATE OR REPLACE PROCEDURE formata_fone (p_fone IN OUT varchar2)
IS

BEGIN P_fone := ( || substr(p_fone, 1, 3) || ) || substr(p_fone, 4, 3) || - || substr(p_fone, 7); END formata_fone; / As instrues para criao do procedimento podem ser digitadas diretamente no prompt do SQL*Plus ou em um arquivo com extenso sql. Se o cdigo for escrito diretamente no prompt ao teclar enter aps a barra ( / ) ser compilado e o procedimento ser criado. Uma mensagem informar se o procedimento foi criado com sucesso ou com erros.

1.5.4. Visualizao de erros de compilao Quando as compilaes no so bem sucedidas a instruo show errors pode ser utilizada para visualizar os erros que ocorreram: Sintaxe: SQL> show errors resultado: Erros para PROCEDURE REAJUSTE: LINE/COL -------8/2 10/26 ERROR ------------------------------------------PL/SQL: SQL Statement ignored PL/SQL: ORA-00904: nome invlido de coluna

1.5.5. Utilizao de procedimentos Os procedimentos podem ser chamados atravs do SQL*Plus, de outros procedimentos ou funes ou de outros aplicativos pr compilados. Exemplo 1: Para chamar procedimentos a partir do prompt do SQL*Plus: Este exemplo utiliza a procedure reajuste que opera com parmetros de entrada: SQL> execute reajuste(7934, 10) Procedimento PL/SQL concludo com sucesso. Exemplo 2: Para chamar o procedimento de um bloco PL/SQL annimo: Este exemplo utiliza a procedure reajuste (que opera com parmetros de entrada) e a procedure consulta_emp (que opera com parmetros de sada): 1. Editar as instrues em um arquivo com extenso sql SQL> edit usa_proc.sql ACCEPT p_cod PROMPT 'cdigo do funcionrio..... ' ACCEPT p_perc PROMPT 'percentual de aumento..... ' VARIABLE g_nome varchar2(25) VARIABLE g_sal number DECLARE v_nome EMP.EMPR_NOME_DS%type; v_sal EMPR.sal%type; BEGIN SELECT EMPR_NOME_DS, sal INTO v_nome, v_sal FROM EMPR WHERE EMPRno = &p_cod; reajuste(&p_cod, &p_perc); consulta_emp(&p_cod, :g_nome, :g_sal); END; / PRINT g_nome

g_sal

2. Execute o bloco SQL> @ c:\usa_proc.sql 3. Resultado: digite o cdigo do funcionrio..... 7934 digite o percentual de aumento..... 10 Procedimento PL/SQL concludo com sucesso. Exemplo 3: Este exemplo utiliza a procedure formata_fone (que opera com parmetros IN OUT). Digite no prompt do SQL: Variable g_fone varchar2(15) Begin :g_fone := 01150819700; end; / Print g_fone Execute formata_fone(:g_fone) Print g_fone 1.5.6. Passagem de Parmetros A passagem de parmetros pode ser feita de trs maneiras: Por posio: Os parmetros reais so listados de acordo com a ordem dos parmetros formais. Por identificao: Os parmetros reais so precedidos da identificao do parmetro formal, podendo ser listados arbitrariamente. Combinada: Os parmetros passados por posio devem ocupar os primeiros lugares da lista.

Exemplo: CREATE OR REPLACE PROCEDURE incluir_dept (p_nome in dept.dname%type default sem nome ainda, p_loc in dept.loc%type default NC) is BEGIN Insert into dept(deptno, dname, loc) values(deptno_seq.nextval, p_nome, p_loc); END incluir_dept; / A seguir so exemplificadas as maneiras possveis de passagem de parmetros para a utilizao da procedure incluir_dept Por posio: SQL> EXECUTE incluir_dept; o prximo valor da sequence e os valores default sero includos seguindo a ordem de declarao dos parmetros formais.

SQL> EXECUTE Incluir_dept(R H, SC); os parmetros reais sero passados para os parmetros formais de acordo com a ordem de declarao dos parmetros formais. Por identificao: SQL> EXECUTE Incluir_dept( p_loc => SP, p_nome => Treinamento); os parmetros reais so precedidos da identificao dos parmetros formais e do sinal de atribuio => Por combinao: SQL> EXECUTE Incluir_dept(p_loc => RJ); os parmetros que no esto listados recebero os valores defaut.

Resultado: SQL> select * from dept; DEPTNO ---------10 20 30 40 1 3 4 5 DNAME -------------ACCOUNTING RESEARCH SALES OPERATIONS sem nome ainda R H Treinamento sem nome ainda LOC ------------12 DALLAS CHICAGO BOSTON NC SC SP RJ

8 linhas selecionadas. 1.5.7. Aninhamento de procedimentos (subprocedimentos) Pode-se criar um procedimento dentro de outro procedimento, este recurso chamado, tambm, de procedimentos em nveis. O exemplo a seguir cria a procedure exemplo_sub, nesta procedure est sendo criada uma outra procedure (log_usurio). Note que logo aps a clusula IS j indicada a sub procedure, somente aps a sua declarao completa que o corpo da procedure principal declarado. CREATE OR REPLACE PROCEDURE exemplo_sub 3 (p_id in EMPR_NUME_NR%type) IS PROCEDURE log_usuario IS BEGIN Insert into log_tabela (user_id, log_data) Values(user, sysdate); END log_usuario; BEGIN Delete from EMPR Where EMPRno = p_id; Log_usuario; END exemplo_sub; / A procedure principal (exemplo_sub) utiliza a sub procedure (log_usurio)., neste caso a tabela log_tabela ir guardar a identificao do usurio e a data da operao pois a procedure principal faz uma excluso na tabela EMPR.

No esquea de criar a tabela para executar o exemplo: Create table log_tabela (user_id varchar2(10), log_data date);

Utilizao: SQL> execute exemplo_sub(7934); Procedimento PL/SQL concludo com sucesso. SQL> select * from log_tabela;

USER_ID LOG_DATA ---------- -------SCOTT 29/04/04 1.6. Funes As funes so muito semelhantes aos procedimentos, o que as difere, do ponto de vista estrutural, a incluso da clusula return. A clusula return tambm implementa a diferena conceitual entre as procedures e as functions, isto , nas funes existe a obrigatoriedade de um retorno rotina chamadora, pode-se dizer que uma funo chamada como parte de uma expresso. Sintaxe: CREATE [ OR REPLACE] FUNCTION nome_funo [parmetro [in] tipo_parmetro, ... return tipo_do_retorno {IS ou AS} BEGIN corpo_da_funo END nome_funo; onde: Create or replace Nome_procedimento parmetro [parmetro [in] Tipo_parmetro return tipo_do_retorno IS ou AS instruo para criao ou substituio do procedimento nome que ser dado ao procedimento nome do parmetro que poder ser somente para entrada tipo de dado que o parmetro poder aceitar Indica o retorno do controle a rotina chamadora com o valor que ser devolvido tem a mesma funo e indicam o bloco que estar associado ao procedimento, substitui a palavra reservada DECLARE. respectivamente o incio do bloco, o conjunto de instrues do procedimento e o final do bloco.

BEGIN corpo_do_procedimento END

Exemplos: CREATE OR REPLACE FUNCTION descobrir_salario (p_id in EMP.EMPRno%type) return number IS v_salario EMPR.sal%type := 0; BEGIN Select sal into v_salario From EMPR Where EMPRno = p_id;

Return v_salario; End descobrir_salario; / Utilizao: SQL> variable g_sal number SQL> execute :g_sal := descobrir_salario(7900) SQL> print g_sal ATENO: Uma funo que contm instrues DML no pode ser utilizada no SQL em operaes DML. O exemplo a seguir ilustra est situao: CREATE OR REPLACE FUNCTION exemplo_dml (p_sal number) return number IS BEGIN Insert into EMPR(EMPR_NUME_NR, EMPR_NOME_DS, sal, hiredate, deptno) Values(37, Sandra, p_sal, sysdate, 15); Return (p_sal + 300); End exemplo_dml; / Utilizao: SQL> Update EMPR set sal = exemplo_dml(5000) Where EMPRno = 7900; Erro ocasionado: Update EMPR set sal = exemplo_dml(5000) * ERRO na linha 1: ORA-04091: a tabela SCOTT.EMP mutante; talvez o gatilho/funo no possa localiz-la ORA-06512: em "SCOTT.EXEMPLO_DML", line 6 1.7. Resumo das diferenas entre procedure e function Procedure chamada em uma declarao SQL, blocos PL/SQL ou por uma aplicao No contm a clausula return no cabealho Pode retornar nenhum, um ou vrios valores Pode devolver um retorno rotina chamadora Function chamada como parte de uma expresso Contm a clausula return no cabealho Retorna somente um valor Retorna obrigatoriamente um valor para a rotina chamadora.

1.8. Trigger So blocos PL/SQL ou Procedures PL/SQL associadas tabelas, vises, esquemas ou bancos de dados. So disparados automaticamente antes ou depois da ocorrncia de um evento. Podem ser classificados em: Trigger de aplicao disparado quando evento envolve uma aplicao em particular, este tpico no ser explorado.

Trigger de banco disparado quando ocorre uma operao DML para insero, alterao ou excluso de dados ou quando ocorre um evento associado ao banco, como exemplo o efetuar logon de um usurio. Podem ser implantados, entre outros, para: o o o o o o Implantao de regras de negcios Manuteno da integridade referencial Implantao de segurana Manuteno de um registro histrico das alteraes Gerao de valores de coluna, incluindo valores de chave primria Replicao de dados

Sintaxe: CREATE [OR REPLACE] TRIGGER [esquema.]nome_trigger {BEFORE ou AFTER} [evento]ON [esquema.]tabela_nome [referencing Old as valor_anterior ou NEW as valor_novo) {nvel de linha ou nvel de instruo} [WHEN (condio)]] DECLARE BEGIN corpo_trigger END; / onde: Create or Replace Trigger Esquema Nome_trigger Before After evento On tabela_nome Referencing Old as valor_anterior ou NEW as valor_novo instruo para criao ou substituio do Trigger Nome do esquema ao qual pertence o objeto Identificador do trigger Indica que a execuo do trigger ser antes da realizao do evento Indica que a execuo do trigger ser depois da realizao do evento Define qual o tipo de instruo que ir provocar o disparo do trigger. As instrues possveis so insert, update ou delete. Indica a tabela que est associada instruo Especifica os identificadores das variveis que iro armazenar os valores antigos e novos. Old e New so pseudocolunas que auxiliam na manipulao das linhas afetadas.

Nvel de linha

disparado uma vez para cada linha afetada pela instruo identificado por FOR EACH ROW

Nvel de instruo When condio

disparado antes ou depois da instruo S pode ser utilizada em trigger de linha. Indica que a trigger ser disparada somente quando a condio for verdadeira.

Exemplo 1: Criar um trigger para no permitir a insero ou alteraes da coluna salrio para valores superiores a 15000, caso o cargo do funcionrio no seja Presidente ou Vendedor. SQL> 2 3 4 5 6 7 8 9 10 11 CREATE OR REPLACE TRIGGER restringe_salrio BEFORE Insert or Update OF sal ON Scott.emp FOR EACH ROW BEGIN If not (:new.job in('PRESIDENT', 'SALES')) And :new.sal > 15000 Then RAISE_APPLICATION_ERROR(-20202, 'O funcionrio no pode ter este aumento de salrio'); END IF; END; /

Quando um usurio tentar realizar uma operao de insero ou alterao que infrinja as regras definidas no trigger para o valor de salrio, a mensagem de erro ser apresentada conforme exemplo a seguir: SQL> insert into sCOTT.emp(EMPR_NUME_NR, EMPR_NOME_DS, EMPR_SERV_DS, sal, deptno) values 2* (135, 'MARCOS', 'CLERK', 15010, 10) * ERRO na linha 1: ORA-20202: O funcionario n?o pode ter este aumento de salario ORA-06512: em "SYS.RESTRINGE_SALARIO", line 5 ORA-04088: erro durante a execuc?o do gatilho 'SYS.RESTRINGE_SALARIO' ATENO: Os triggers no podem emitir commit ou rollback e no podem conter variveis Long ou Long raw Exemplo 2: Criar um trigger para no permitir a insero de funcionrios fora do horrio comercial SQL> 2 3 4 5 6 7 8 9 10 CREATE OR REPLACE TRIGGER seguro_emp BEFORE INSERT ON SCOTT.EMP BEGIN IF(TO_CHAR(SYSDATE, 'DY') IN ('SAT','SUN')) OR (TO_CHAR(SYSDATE, 'HH24:MI') NOT BETWEEN '08:00' AND '18:00') THEN RAISE_APPLICATION_ERROR(-20500, 'Inseres de funcionrios somente no horrio comercial'); end if; end; /

A tentativa de inserir novos funcionrios fora do horrio previsto resultara no erro a seguir: SQL> insert into SCOTT.emp(EMPR_NUME_NR, EMPR_NOME_DS, sal, deptno) 2 values(7935, 'SANDRA', 1203, 10); insert into SCOTT.emp(EMPR_NUME_NR, EMPR_NOME_DS, sal, deptno) * ERRO na linha 1: ORA-20500: Inserc?es de funcionarios somente no horario comercial ORA-06512: em "SYS.SEGURO_EMP", line 5 ORA-04088: erro durante a execuc?o do gatilho 'SYS.SEGURO_EMP' Nos exemplos 1 e 2 o trigger disparado sempre antes da ao ser concretizada, este um recurso til para fazer validaes, j no exemplo 3 apresentado um trigger disparado depois de um evento, este recurso til para fazer auditoria, por exemplo.

Exemplo: Criar um trigger para registrar as alteraes realizadas em uma tabela, valores antigos e novos, os dados do usurio que realizou a alterao e a data da ocorrncia: CREATE OR REPLACE TRIGGER auditar_emp AFTER DELETE OR INSERT OR UPDATE On Scott.emp FOR EACH ROW BEGIN INSERT INTO table_aud_emp(user_name, data,antigo_nome, novo_nome, antigo_salario, novo_salario) values (user, sysdate, :old.ename,:new.ename,:old.sal, :new.sal); end; / Aps a realizao de qualquer operao DML a tabela de auditoria tabela_aud_emp receber um registro com as informaes do autor e data da operao, valores anteriores e valores atuais para nome e salrio do funcionrio, conforme o resultado apresentado a seguir: SQL> 2 insert into SCOTT.emp(EMPR_NUME_NR, EMPR_NOME_DS, sal, deptno) values(7935, 'SANDRA', 1203, 10);

SQL> update scott.emp 2 set sal = 1300 3 where EMPR_NOME_DS = 'SANDRA'; Resultado: SQL> select * from table_aud_emp;
USER_NAME DATA SYS 05/05/04 SYS 05/05/04 ID ANTIGO_NOME NOVO_NOME ANTIGO_SALARIO NOVO_SALARIO SANDRA 1203 SANDRA SANDRA 1203 1300

ATENO: Old e New so identificadores utilizados somente em triggers de linha, deve-se utilizar o prefixo : e fazer referncia coluna, por exemplo :old.ename. A tabela apresentada a seguir mostra os valores assumidos para :old e :new para cada evento: Evento INSERT :old No deve ser definido, Todas as colunas contm nulos. UPDATE Valores das colunas antes da atualizao (antigos) DELETE Valores das colunas antes da excluso :new Novos valores que sero inseridos Valores das colunas aps a atualizao (novos) No deve ser definido, todas as colunas contero nulos.

Select trigger_type, table_name, triggering_event From user_triggers Where...

Para saber mais consulte: Livros: Autor Urman, Scott Oliveira, Celso H. Poderoso de Morelli, Eduardo Terra SILBERSCHATZ, Abraham, KORTH, Henry F. e SUDASRSHAN, S., Ttulo Urman, Scott, Oracle 8 Programao PL/SQL, McGraw Hill (1999) Oliveira, Celso H. Poderoso de, Oracle 8i Pl/Sql - Guia De Consulta Rapida, Novatec, 2000 Morelli, Eduardo Terra, Oracle 8i Fundamental SQL, PL/SQL e Administrao, Editora rica, 2000 Sistema de Banco de dados. So Paulo: Makron Books, 1999

Oracle8i Administrao de Bancos de Dados. Rio de Janeiro: Editora Cincia Moderna Sites: Oracle imasters SLQMagazine Jose Valter Stanford University Oracle Oracle imasters SLQMagazine

http://otn.oracle.com/sample_code/tech/pl_sql/index.html http://www.imasters.com.br http://www.sqlmagazine.com.br http://josevalter.com.br/download/sql/Dicas%20Oracle%20SQL.PD F http://www-db.stanford.edu/~ullman/fcdb/oracle/orplsql.html#variables%20and%20types http://www.orafaq.com/faqplsql.htm#WHAT http://otn.oracle.com/sample_code/tech/pl_sql/index.html http://www.imasters.com.br http://www.sqlmagazine.com.br

i Puga, Sandra, Rissetti, Gerson ...