Вы находитесь на странице: 1из 21

Tutorial de PL/SQL

Para Oracle 9 por Miguel Rodrigues Fornari

Sumrio
1. Introduo....................................................................................................................3 2. Estrutura geral de um programa PL/SQL...................................................................3 2.1 Execuo de PL/SQL............................................................................................4 3. Variveis e constantes.................................................................................................4 3.1 Vetores...................................................................................................................5 3.2 Registros................................................................................................................6 3.3 Atribuio de valores variveis..........................................................................6 3.4 Declarao de Constantes.....................................................................................6 4. Cursores.......................................................................................................................7 4.1 Laos FOR em Cursores.......................................................................................8 4.2 Cursores Dinmicos..............................................................................................9 4.2.1 Manipulao de cursores dinmicos............................................................10 5. Estruturas de Controle de Fluxo................................................................................10 5.1 Comando IF.........................................................................................................11 5.2 Comando CASE..................................................................................................11 5.3 Laos de iterao.................................................................................................11 5.3.1 Comando FOR-LOOP.................................................................................11 5.3.2 Comando WHILE-LOOP............................................................................12 5.3.3 Comando GOTO..........................................................................................12 6. Modularidade.............................................................................................................12 6.1 Subprogramas......................................................................................................13 6.2 Pacotes.................................................................................................................14 6.3 Tratamento de excees......................................................................................15 7. Funes pr-definidas...............................................................................................17 7.1 Funes de valor simples....................................................................................17 7.1.1 Funes numricas.......................................................................................18 7.1.2 Funes de caracteres retornando caracteres...............................................18 7.1.3 Funes de caracteres que retornam valores numricos............................19 7.1.4 Funes de data............................................................................................19 7.1.5 Funes de converso..................................................................................20 8. Visualizao de valores na tela.................................................................................20

1. Introduo
Este tutorial procurar resumir brevemente os principais pontos de PL/SQL, para o SGBD Oracle, verso 9. No se trata de material completo, com todos os detalhes de sintaxe e semntica. apenas um complemento para as aulas da disciplina de Bancos de Dados II, do curso de Sistemas de Informao, na ULBRA. Se o leitor necessitar, sugiro o material disponvel no site Technet-Oracle (http://technet.oracle.com), especialmente o manual de usurio do PL/SQL (http://technet.oracle.com/docs/products/oracle9i/doc_library/release2/appdev.920/a96624/to c.htm), do qual os exemplos foram copiados e alguns trechos traduzidos.

2. Estrutura geral de um programa PL/SQL


Um modo interessante de entender PL/SQL olhando inicialmente um programa exemplo. O programa abaixo processa uma ordem de compra de "Tennis Racket".
DECLARE qty_on_hand NUMBER(5); BEGIN SELECT quantity INTO qty_on_hand FROM inventory WHERE product = 'TENNIS RACKET' FOR UPDATE OF quantity; IF qty_on_hand > 0 THEN -- check quantity UPDATE inventory SET quantity = quantity - 1 WHERE product = 'TENNIS RACKET'; INSERT INTO purchase_record VALUES ('Tennis racket purchased', SYSDATE); ELSE INSERT INTO purchase_record VALUES ('Out of tennis rackets', SYSDATE); END IF; COMMIT; END;

Primeiro, declara uma varivel to tipo NUMBER(5) para armazenar a quantidade de raquetes existentes. Ento seleciona a quantidade existente em estoque, que est armazenada no banco, atribuindo o valor varivel qty_on_hand. Se a quantidade for maior que zero, atualiza o estoque e registra a venda, seno informa a falta do item. PL/SQL trata-se de uma linguagem completa, no sentido em que possui comandos para declarao e manipulao de variveis e controle de fluxo de processamento, definir procedimentos e funes, tratar erros, alm de integrar comandos SQL. No h comandos para vdeo ou teclado, que devero ser controlados por outra linguagem. PL/SQL uma linguagem estruturada em blocos (procedimentos, funes e blocos no nomeados), que podem conter zero ou mais sub-blocos. Tipicamente, cada bloco corresponde a um problema a ser resolvido. Em cada bloco possvel declarar variveis de escopo local, que deixam de existir quando o bloco termina.

Tipicamente, cada bloco composto de trs partes: declaraes, comandos e tratamento de excees. Apenas a seo de comandos obrigatria.
[DECLARE declaraes] BEGIN comandos [EXCEPTIONS tratamento de excees] END;

2.1 Execuo de PL/SQL A execuo de trechos de programas utilizando PL/SQL est integrada com o banco de dados. Em tempo de execuo, Oracle identifica uma chamada a um bloco de comandos PL/SQL, identifica comandos SQL que podem ser resolvidos pelo engine do banco envia o restante do cdigo para o excutor de PL/SQL, como mostra figura 1.

FIGURA 1. Esquema de execuo de blocos de comandos PL/SQL. Um procedimento ou funo pode ser criado no banco de dados e utilizado por todas as aplicaes e usurios que tiverem direito, atravs de um comando CALL. Estes procedimentos so chamados de Stored Procedures.

3. Variveis e constantes
PL/SQL permite declarar variveis e constantes e utiliz-las em qualquer comando ou expresso dentro do seu escopo. As variveis devem ser declaradas antes de serem utilizadas. Variveis podem ser de qualquer tipo pr-existente no SQL, a saber: CHAR(num_caracteres): permite armazenar strings com um tamanho mximo delimitado. VARCHAR2(num_caracteres): permite armazenar strings com um tamanho mximo delimitado. A diferena com anterior est em no armazenar caracteres em branco ao final da string. Disto resulta algumas situaes no habituais, aps as atribuies realizadas.

C1 CHAR(10); VC1 VARCHAR2(10); VC2 VARCHAR2(10); C1 = 'RICO ' VC1 = 'RICO ' VC2 = 'RICO'

A partir das declaraes das variveis e atribuies acima, tem-se que VC1 diferente que C1, pois apenas C1 conserva os espaos em branco ao final, enquanto VC1 no os conserva, porm VC1 = VC2. BYNARY_INTEGER: nmeros inteiros entre -231 at 231 -1 . NUMBER([nm_dgitos, preciso]): suporta nmeros entre 1-130 e 10125, com um certo nmero de casas decimais, especificadas no parmetro preciso.

Este tipo possui alguns subtipos. DOUBLE PRECISION e FLOAT permitem at 38 casas decimais de preciso, enquanto REAL permite apenas 18 casas decimais. INT, INTEGER e SMALLINT representam nmeros inteiros de at 18 dgitos. PLS_INTEGER: tambm armazena nmeros inteiros entre 2-31 at 231 -1, porm as funes matemticas operam com maior eficincia sobre variveis deste tipo, sendo prefervel para clculos mais complexos. BOOLEAN: variveis booleanas podem armazenar os valores TRUE, FALSE e NULL. DATE: armazena valores de data, incluindo o horrio. O formato default para datas est definido em um parmetro do Oracle, chamado NLS_DATE_FORMAT. TIMESTAMP: este tipo armazena a data, hora, minutos e segundos. Por exemplo, '1999-06-22 07:48:53.275'. TIMESTAMP WITH TIME ZONE: este tipo inclui a zona de tempo. Por exemplo, '1999-10-31 09:42:37.114 +02:00'.

A declarao de variveis est mostrada nos exemplos abaixo, com o nome da varivel seguido pelo tipo.
part_no NUMBER(4); in_stock BOOLEAN;

3.1 Vetores O tipo VARRAY permite declarar vetores, compostos por uma coleo ordenada de elementos do mesmo tipo. Cada elemento possui um ndice nico, que indica sua posio no vetor. No necessrio indicar um tamanho mximo para o vetor. Depois de criado o tipo, podem ser declaradas uma ou mais variveis do tipo. A sintaxe de criao do tipo :

TYPE type_name IS VARRAY [(limite_tamanho) ] OF element_type [NOT NULL];

Para se referir a um elemento, utiliza-se o ndice entre parnteses. Por exemplo:


DECLARE TYPE Staff IS VARRAY OF Employee; staffer Employee; FUNCTION new_hires (hiredate DATE) RETURN Staff IS BEGIN ... END; BEGIN staffer := new_hires('10-NOV-98')(5); END;

3.2 Registros Registros permitem a composio de variveis de tipos diferentes em um mesmo grupo lgico. Os nomes dos campos devem ser nicos. Um campo pode ser de um tipo registro ou vetor, de modo ortogonal. Uma vez criado o tipo registro, podem ser declaradas variveis deste tipo. Por exemplo:
DECLARE TYPE TimeRec IS RECORD (hours SMALLINT, minutes SMALLINT); TYPE MeetingTyp IS RECORD ( date_held DATE, duration TimeRec, -- nested record location VARCHAR2(20), purpose VARCHAR2(50));

3.3 Atribuio de valores variveis possvel atribuir valores a variveis de trs maneiras. A mais comum o operador de atribuio (:=), como mostram os exemplos abaixo.
tax := price * tax_rate; valid_id := FALSE; bonus := current_salary * 0.10; wages := gross_pay(emp_id, st_hrs, ot_hrs) - deductions;

A segunda maneira de atribuir valores utilizando o comando SELECT atribuindo seu retorno uma varivel. O comando SELECT deve ser construdo de modo a retornar um valor, no uma lista de valores. Por exemplo, atribuir 10% do salrio para a varivel bonus.
SELECT sal * 0.10 INTO bonus FROM emp WHERE empno = emp_id;

A terceira maneira de atribuir valores atravs de passagem de parmetros em chamadas de procedimentos e funes, o que ser visto mais adiante. 3.4 Declarao de Constantes A declarao de constantes semelhante de variveis, acrescentando a palavra chave CONSTANT e, imediatamente, atribuindo o valor. Por exemplo,

credit_limit CONSTANT REAL := 5000.00;

4. Cursores
Oracle utiliza reas de trabalho para executar comandos SQL e armazenar a informao processada. Um cursor permite percorrer esta rea de trabalho para ler as informaes armazenadas. H dois tipos de cursores: implcitos e explcitos. Cursores implcitos so criados pelo Oracle a cada execuo de um comando SQL, mas no podem ser utilizados em um programa em PL/SQL. Cursores explcitos podem ser manipulados em um programa PL/SQL. A declarao de um cursor segue a sintaxe DECLARE CURSOR nome_cursor IS comando_select; Por exemplo,
DECLARE CURSOR c1 IS SELECT empno, ename, job FROM emp WHERE deptno = 20;

A declarao do cursor associa um comando SQL a ele. Um curso permitir ler, tupla a tupla, o resultado de um consulta. A semelhana de um arquivo, o cursor deve ser aberto, percorrer uma a uma cada tupla, at o final do conjunto de dados.

FIGURA 1. Cursor O programa de utilizar os comandos OPEN, FETCH e CLOSE. O comando OPEN executa a consulta associada ao cursor, obtm um conjunto de tuplas como resposta a consulta e posiciona o cursor na primeira tupla. O comando FETCH retorna os valores da tupla corrente e avana uma posio na lista. O comando CLOSE desabilita o cursor, liberando o espao de memria ocupado pelo conjunto resposta. A sintaxe do comando OPEN :
OPEN nome_cursor;

A sintaxe do comando CLOSE :


CLOSE nome_cursor;

E do comando FETCH
FETCH nome_curso INTO [lista_variveis].

A lista de variveis pode conter uma ou mais variveis. H duas alternativas: utilizar variveis individuais, de tipos correspondentes ao retorno do SELECT; ou utilizar uma

varivel de um tipo registro adequado ao SELECT. Para o cursor declarado acima, possvel:
FETCH c1 INTO my_empno, my_ename, my_deptno;

ou
FETCH c1 INTO my_record;

Todos cursores possuem quatro propriedades que podem ser teis em um programa:
%FOUND: indica se a ltima operao FETCH encontrou uma tupla. Seu valor verdadeiro at a ltima tupla. %NOTFOUND: indica se a ltima operao FETCH no encontrou uma 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.

Para testar se o cursor retornou algum valor vlido ou j atingiu o final do conjunto, pode-se testar a propriedade FOUND do cursor. Por exemplo,
FETCH C1 INTO .... WHILE C1%FOUND LOOP Comandos FETCH C1 INTO .... END LOOP

Um cursor pode, ainda, ter parmetros. Deste modo, a definio do cursor fica alterada:
DECLARE CURSOR emp_cursor(dnum NUMBER) IS SELECT sal, comm FROM emp WHERE deptno = dnum;

A inicializao do cursor, que pode ser por um comando OPEN ou FOR-LOOP feita passando o valor do parmetro. Por exemplo:
FOR emp_record IN emp_cursor(20) LOOP END IF; END LOOP;

4.1 Laos FOR em Cursores Em muitas situaes, percorrer todas as tuplas resultantes de uma tabela pode ser realizado com o comando FOR, e no com OPEN-FETCH-CLOSE. Um lao FOR em

cursores exige uma varivel, que declarada implicitamente dentro do comando. No exemplo abaixo, a varivel emp_rec do tipo registro. Para referir campos individuais da varivel, utilizada a notao ponto (.).
DECLARE CURSOR c1 IS SELECT ename, sal, hiredate, deptno FROM emp; ... BEGIN FOR emp_rec IN c1 LOOP ... salary_total := salary_total + emp_rec.sal; END LOOP;

4.2 Cursores Dinmicos Embora a maioria dos programas em PL/SQL execute comandos previsveis, que permitem uma declarao esttica de um cursor, em algumas situaes necessrio alterar dinamicamente, em tempo de execuo, o comando SELECT que define o cursor. As seguintes situaes so tpicas:

necessrio utilizar um comando de definio de dados (DDL), como o CREATE, um comando de atribuio ou revogao de direitos (GRANT e REVOKE) OU UM comando de CONTROLE de sesso (ALTER SESSION). Em PL/SQL, estes comandos so necessariamente dinmicos. necessrio compor a clausula WHERE de acordo com condies que o usurio escolhe ou no na interface.

O comando adequado o EXECUTE IMMEDIATE, cuja sintaxe :


EXECUTE IMMEDIATE comando_sql [INTO {varivel1, varivel2, . ]... | varivel_registro}] [USING parmetro1, parmetro2, ...};

O comando SQL especificado na primeira. Na clausula INTO, indica-se as variveis que recebero o retorno do comando, ou apenas uma varivel do tipo registro. Na clausula USING indica-se os parmetros do comando. Abaixo h um conjunto de exemplos:
EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE TRUE'; - executa o comando ALTER SESSION. EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)'; executa o comando de criao de uma tabela. sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)'; EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location; - executa o comando INSERT, colocando os valores passados por parmetro na clausula USING.

sql_stmt := 'SELECT * FROM emp WHERE empno = :1'; EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id; - executa o commando SELECT, atribuindoa resposta varivel emp_rec. A identificao do empregado passada por parmetro. EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :num' USING dept_id; - retira uma tupla da tabela dept.

4.2.1 Manipulao de cursores dinmicos No caso de comandos SELECT que retornem mais de uma tupla no conjunto resposta, necessrio utilizar os comandos OPEN-FETCH-CLOSE para percorrer, tupla a tupla, o conjunto resposta. Para o comando OPEN utiliza-se a seguinte variao sinttica:
OPEN {varivel_cursor } FOR string_sql [USING argumento1[, argumento2]...];

Uma varivel do tipo cursor deve declarada, a priori. O comando SQL montado em uma varivel do tipo string, conforme a necessidade do programa, e colocado na clausula FOR. Se houverem parmetros no comando SQL, os argumentos so passados na clausula USING. O exemplo abaixo ilustra este caso. Veja que a varivel emp_cv declarada como sendo do tipo cursor e no comando SELECT h um parmetro, cujo valor atribudo na clausula USING.
DECLARE TYPE EmpCurTyp IS REF CURSOR; -- define weak REF CURSOR type emp_cv EmpCurTyp; -- declare cursor variable my_ename VARCHAR2(15); my_sal NUMBER := 1000; BEGIN OPEN emp_cv FOR -- open cursor variable 'SELECT ename, sal FROM emp WHERE sal > :s' USING my_sal; ... END;

Os comandos FETCH e CLOSE permanecem semelhantes, como mostra o trecho de cdigo a seguir:
FETCH emp_cv INTO my_ename, my_sal; WHILE emp_cv%FOUND = TRUE LOOP - - comandos FETCH emp_cv INTO my_ename, my_sal; END LOOP; CLOSE emp_cv; -- close cursor variable

5. Estruturas de Controle de Fluxo


As estruturas de controle de fluxo de comandos permitem definir a execuo dos comandos de acordo com uma seqncia adequada. PL/SQL possui os comandos IF-THENELSE, CASE, FOR-LOOP, WHILE-LOOP, EXIT-WHEN, e GOTO.

5.1 Comando IF O comando IF-THEN-ELSE permite escolher entre dois caminhos alternativas, de acordo com uma condio booleana. Por exemplo,
IF acct_balance >= debit_amt THEN UPDATE accounts SET bal = bal - debit_amt WHERE account_id = acct; ELSE INSERT INTO temp VALUES (acct, acct_balance, 'Insufficient funds'); -- insert account, current balance, and message END IF;

5.2 Comando CASE Para escolher entre vrias alternativas (valores, comandos), pode utilizar o comando CASE. Cada condio expressa em uma clausula WHEN e a ao associada atravs da palavra-chave THEN. Por exemplo, o comando abaixo possui quatro alternativas, uma para quadrados (square), para crculos (circle), retngulos (rectangle) e outra alternativa para os demais casos (ELSE).
-- This CASE statement performs different actions based -- on a set of conditional tests. CASE WHEN shape = 'square' THEN area := side * side; WHEN shape = 'circle' THEN BEGIN area := pi * (radius * radius); DBMS_OUTPUT.PUT_LINE('Value is not exact because pi is irrational.'); END; WHEN shape = 'rectangle' THEN area := length * width; ELSE BEGIN DBMS_OUTPUT.PUT_LINE('No formula to calculate area of a' || shape); RAISE PROGRAM_ERROR; END; END CASE;

5.3 Laos de iterao Em PL/SQL existem os seguintes laos de iterao: 5.3.1 Comando FOR-LOOP O comando FOR-LOOP permite executar uma seqncia de comandos um nmero determinado de vezes. A sintaxe :
FOR varivel IN limite_inferior..limite superior LOOP -- comandos END LOOP;

Por exemplo, o comando FOR-LOOP repete 500 vezes o comando INSERT.


FOR num IN 1..500 LOOP INSERT INTO roots VALUES (num, SQRT(num)); END LOOP;

5.3.2 Comando WHILE-LOOP O comando WHILE-LOOP executa uma seqncia de comandos at que uma condio lgica resulte falsa. A condio lgica avaliada antes da execuo dos comandos. A sintaxe :
WHILE condio_Lgica LOOP Comandos END LOOP;

Por exemplo, no trecho abaixo o comando SELECT executado enquanto a varivel for menor que 2500.
WHILE salary <= 2500 LOOP SELECT sal, mgr, ename INTO salary, mgr_num, last_name FROM emp WHERE empno = mgr_num; END LOOP;

5.3.3 Comando GOTO O comando GOTO permite alterar a seqncia de execuo sem nenhuma condio, para qualquer ponto do programa, indicado por um label. O label indicado por um nome entre dois sinais de menor e dois de maior, como mostra o exemplo abaixo:
IF rating > 90 THEN GOTO calc_raise; -- branch to label END IF; ... <<calc_raise>> IF job_title = 'SALESMAN' THEN -- control resumes here amount := commission * 0.25; ELSE amount := salary * 0.10; END IF;

6. Modularidade
Modularidade permite dividir uma aplicao em trechos menores, mais fceis de serem desenvolvidos e testados. PL/SQL permite a criao de procedimentos, funes e pacotes.

6.1 Subprogramas PL/SQL possui dois tipos de subprogramas, chamados procedimentos e funes, que podem receber parmetros. Um subprograma deve ser declarado antes de ser chamado. A declarao de um procedimento segue a seguinte sintaxe:
PROCEDURE nome_procedimento [(lista_de_parmetros)] IS [declaraes locais] BEGIN comandos [ EXCEPTION tratamento de excees ] END ;

Onde,
lista_de_parmetros := [IN | OUT | INOUT] nome_parmetro1 tipo_parmetro1 [, [IN | OUT | INOUT] nome_parmetro2 tipo_parmetro2] ... [, [IN | OUT | INOUT] nome_parmetroN tipo_parmetroN]

A lista de parmetros opcional e pode ter um ou mais parmetros. Cada parmetro pode ser IN, OUT ou INOUT. Parmetros IN so o tipo default, permitem receber um valor para o procedimento utilizar. Parmetros OUT tm seu valor alterado durante o procedimento e parmetros INOUT combinam os dois tipos. O exemplo abaixo ilustra um procedimento.
PROCEDURE award_bonus (emp_id NUMBER) IS bonus REAL; comm_missing EXCEPTION; BEGIN -- executable part starts here SELECT comm * 0.15 INTO bonus FROM emp WHERE empno = emp_id; IF bonus IS NULL THEN RAISE comm_missing; ELSE UPDATE payroll SET pay = pay + bonus WHERE empno = emp_id; END IF; EXCEPTION -- exception-handling part starts here WHEN comm_missing THEN ... END award_bonus;

A chamada de uma funo realizada apenas atravs do nome do procedimento e os parmetros. Os parmetros so posicionais, como no PASCAL e C. Por exemplo,
BEGIN .... award_bnus(304); . END;

A sintaxe para funes inclui o tipo de retorno da funo, como abaixo:


FUNCTION function_name [ ( lista_de_parmetros ) ] RETURN tipo_de_dados

[declaraes locais] BEGIN comandos [ EXCEPTION tratamento de excees ] END ;

O exemplo abaixo ilustra uma funo. O comando RETURN especfica o valor retornado pela funo.
FUNCTION sal_ok (salary REAL, title VARCHAR2) RETURN BOOLEAN IS min_sal REAL; max_sal REAL; BEGIN SELECT losal, hisal INTO min_sal, max_sal FROM sals WHERE job = title; RETURN (salary >= min_sal) AND (salary <= max_sal); END;

A chamada de funes tambm semelhante ao Pascal e C, bastando utilizar o nome da funo. Uma funo pode ser utilizada em qualquer contexto possvel para um valor do mesmo tipo. Por exemplo,
IF sal_ok( 20000, A) THEN . END IF;

6.2 Pacotes Um conjunto de variveis, cursores e procedimentos e funes podem ser agrupados logicamente em pacotes. Um pacote composto de duas partes: especificao e implementao. A especificao permite a declarao de variveis, cursores, tratadores de excees e cabealhos de procedimentos e funes. A implementao contm os procedimentos e funes completas. O exemplo abaixo declara um pacote, chamado emp_actions, composto de dois procedimentos, hire_employee e fire_employee.

CREATE PACKAGE emp_actions AS -- package specification PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...); PROCEDURE fire_employee (emp_id NUMBER); END emp_actions; CREATE PACKAGE BODY emp_actions AS -- package body PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...) IS BEGIN INSERT INTO emp VALUES (empno, ename, ...); END hire_employee; PROCEDURE fire_employee (emp_id NUMBER) IS BEGIN

DELETE FROM emp WHERE empno = emp_id; END fire_employee; END emp_actions;

Apenas o que foi declarado na especificao do pacote visvel externamente. Um pacote pode ser compilado e armazenado no Oracle, podendo ser utilizado por vrias aplicaes. 6.3 Tratamento de excees Quando um erro ocorre em PL/SQL, uma exceo disparada, a exceo normal do programa para e o fluxo de controle do programa desviado para o tratamento de excees associado ao programa ou procedimento. O Oracle trata automaticamente uma srie de excees, como diviso por zero, mas de uma forma padronizada, que consiste em mostrar a mensagem de erro gerada pelo Oracle para o usurio, o que, em geral, no recomendvel. H um grande conjunto de excees no Oracle. Abaixo esto listadas as principais: Exceo
ACCESS_INTO_NULL CASE_NOT_FOUND

Ocorre quando ... O programa tentou atribuir valores nulos a variveis. Nenhuma das codices das clasulas WHEN de um comando CASE foi atentida e no h clasula ELSE. Foi realizada uma tentativa de abrir um cursor (comandos OPEN ou FOR) que j est aberto. Insero de um valor duplo em um campo de valores nicos. Operao ilegal em um cursor, como fechar um cursor no aberto. A converso de uma varivel do tipo caracter para outra do tipo numrico no foi possvel. Usurio ou senha incorretos. Um comando SELECT INTO no retornou nenhum valor para a varivel. O usurio no est logado ao Oracle. Erro interno do PL/SQL.

CURSOR_ALREADY_OPEN

DUP_VAL_ON_INDEX INVALID_CURSOR

INVALID_NUMBER

LOGIN_DENIED NO_DATA_FOUND

NOT_LOGGED_ON PROGRAM_ERROR

Exceo
ROWTYPE_MISMATCH

Ocorre quando ... Atribuio de uma coluna de um cursor para uma varivel de tipo incorreto. Erro interno no armazenamento de dados em memria. O programa tentou acessar um elemento acima do limite mximo do array. O programa tentou acessar um elemento abaixo do limite mnimo do array. Ocorreu um time-out na busca por um recurso necessrio para o processamento de um comando SQL. Um comando SELECT INTO retornou mais de um valor. Ocorreu um erro em uma expresso aritmtica ou funo de converso de valores. Diviso por zero.

STORAGE_ERROR SUBSCRIPT_BEYOND_COUNT

SUBSCRIPT_OUTSIDE_LIMIT

TIMEOUT_ON_RESOURCE

TOO_MANY_ROWS VALUE_ERROR

ZERO_DIVIDE

O exemplo abaixo mostra o tratamento de excees. O programa prev um tipo de tratamento diferente para a diviso por zero.
DECLARE pe_ratio NUMBER(3,1); BEGIN SELECT price / earnings INTO pe_ratio FROM stocks WHERE symbol = 'XYZ'; -- might cause division-by-zero error INSERT INTO stats (symbol, ratio) VALUES ('XYZ', pe_ratio); COMMIT; EXCEPTION -- exception handlers begin WHEN ZERO_DIVIDE THEN -- handles 'division by zero' error INSERT INTO stats (symbol, ratio) VALUES ('XYZ', NULL); COMMIT; ... WHEN OTHERS THEN -- handles all other errors ROLLBACK; END;

Em um programa, possvel ainda declarar novas excees, como mostra o exemplo abaixo.
DECLARE ... comm_missing EXCEPTION; -- declare exception BEGIN ... IF commission IS NULL THEN RAISE comm_missing; -- raise exception END IF; bonus := (salary * 0.10) + (commission * 0.15); EXCEPTION WHEN comm_missing THEN ... -- process the exception

Finalmente, o Oracle possui um grande nmero de cdigos de erro, que podem ser manipulados no tratamento da exceo, atravs das variveis SQLCODE (cdigo numrico) e SQLERRM (mensagem de erro). Estas variveis no podem ser utilizadas diretamente em um comando SQL, devendo ser atribudas a variveis locais. Por exemplo:
DECLARE err_num NUMBER; err_msg VARCHAR2(100); BEGIN ... EXCEPTION WHEN OTHERS THEN err_num := SQLCODE; err_msg := SUBSTR(SQLERRM, 1, 100); INSERT INTO errors VALUES (err_num, err_msg); END;

7. Funes pr-definidas
O SQL Oracle possui um grande conjunto de funes pr-definidas, que podem ser utilizadas pelo programador. Estas funes dividem-se em dois grupos: valores simples, que retornam apenas um valor como resultado; e valores mltiplos, que podem retornar uma tabela de valores. O que segue no uma lista exaustiva de todas as funes. Para tanto, o leitor pode consultar o manual on-line, no endereo http://technet.oracle.com/docs/products/oracle9i/doc_library/901_doc/server.901/a90125/fun ctions2.htm#80856. 7.1 Funes de valor simples Funes de valor simples esto presentes em praticamente todas as linguagens. Sua chamada realizada atribuindo o valor e retorno a uma varivel ou utilizando a funo em uma expresso mais complexa.

7.1.1 Funes numricas Funes numricas aceitam valores de entrada numricos e retornam valores numricos. A maioria delas retornam valores exatos at 38 casas decimais. As funes trigonomtricas COS, COSH, EXP, LN, LOG, SIN, SINH, SQRT, TAN, e TANH so acuradas at 36 casas decimais. As funes trigonomtricas inversas ACOS, ASIN, ATAN e ATAN2 tem preciso de 30 casas decimais. As funes numricas so: ABS( nmero ): valor absoluto do nmero . ACOS ( nmero ): valor, em radianos, do arco cosseno. ASIN ( nmero): valor, em radianos, do arco seno. ATAN (nmero): valor, em radianos, do arco tangente. CEIL (nmero): menor inteiro maior ou igual ao parmetro. COS (nmero): valor do cosseno de um ngulo. COSH (nmero): valor do cosseno hiperblico de um ngulo. EXP (nmero): resultado de enmero. FLOOR (nmero): menor inteiro menor ou igual ao parmetro. LN (nmero): logaritmo neperiano do parmetro. LOG (nmero): logaritmo na base 10 do parmetro. MOD ( dividendo, divisor): calcula o resto da diviso. POWER (n1, n2): calcula n1n2. ROUND (nmero): arredondamento do parmetro. SIGN (nmero): se nmero<0, retorna -1. Se nmero=0, returna 0. Se n>0, returna 1. SIN (nmero): valor do seno de um ngulo. SINH (nmero): valor do seno hiperblico de um ngulo. SQRT (nmero): valor da raiz quadrada de um nmero. TAN (nmero): valor do tangente de um ngulo. TANH (nmero): valor do tangente hiperblica de um ngulo. TRUNC (valor, preciso) : realiza o truncamento do valor para um nmero de casas decimais indicado como preciso.

7.1.2 Funes de caracteres retornando caracteres As funes de caracteres retornam um tipo adequado com o parmetro de entrada. Se o parmetro de entrada for CHAR, o retorno ser CHAR, limitado at 2000 caracteres. Se for VARCHAR2, o retorno ser VARCHAR2, limitado a te 4000 caracteres. So as seguintes

funes: CHR (nmero): retorna o caractere equivalente ao cdigo ASCII passado por parmetro. CONCAT (string1, string2): retorna a string resultante da concatenao dos parmetros. INITCAP (string): retorna um string com a primeira letra maiscula e as demais minsculas. LOWER (string): retornar um string com todas as letras minsculas. REPLACE (string, caracter1, caracter2): troca todas as ocorrncias do caracter1 pelo caracter2; SUBSTR(string, posio, num_caracteres): retorna a substring que comea na posio indicada, com um certo nmero de caracteres. TRIM( caracter FROM string): retorna a string original sem as ocorrncias do caracter indicado. A palavra chave FROM necessria. Ex: TRIM( 0 FROM 002939940) = 293994 UPPER( string): retorna a string com todos os caracteres em maisculo.

7.1.3 Funes de caracteres que retornam valores numricos No PL/SQL as seguintes funes retornam valores numricos: ASCII(caracter): retorna o cdigo ASCII correspondente ao caracter. INSTR(string, substring): retorna a posio da primeira ocorrncia da substring dentro do string. Ex: INSTR(ORACLE, C) = 4. LENGTH(string): retorna o nmero de caracteres da string.

7.1.4 Funes de data Funes de data so aquelas aplicveis a valores do tipo DATE. Com exceo das funes indicadas, todas retornam uma data vlida. ADD_MONTHS ( data, valor): adiciona um certo nmero de meses, indicado no parmetro valor, a data. CURRENT_DATE : retorna a data atual. EXTRACT (campo FROM DATE data): extrai da data o valor do campo indicado. As palavras chaves para indicar os campos so:YEAR, MONTH, DAY, HOUR, MINUTE, SECOND. Ex: EXTRACT(YEAR FROM DATE '1998-03-07') = 1998. LAST_DAY (data): retorna o ultimo dia do ms a qual a data pertence.

MONTHS_BETWEEN ( data1, data2): retorna o nmero de meses entre data1 e data2. Se data1 for posterior, o valor ser positivo. O Oracle a frao correspondente ao ms, quando necessrio. Ex: MONTHS_BETWEEN ('0202-1995','01-01-1995') = 1.03225806. NEXT_DAY (data): retorna o prximo dia til. SYSDATE : retorna dia e hora correntes. TRUNC (data, MONTH ou YEAR): trunca a data para o primeiro dia do ms ou ano correspondente a data, conforme indicado como unidade. EX: TRUNC(27-OCT-92,'YEAR') = 01-JAN-92.

7.1.5 Funes de converso Funes de converso convertem um valor de um tipo de dados para outro. Geralmente o primeiro tipo de entrada e o segundo tipo de sada. CAST(valor AS tipo): converte um valor especificado para um tipo de dado pr-definido ou criado pelo usurio. EX: CAST('22-OCT-1997' AS DATE)= 22-10-1997. TO_CHAR (datetime): converte um tipo de tempo (data ou hora) para VARCHAR2. TO_CHAR (number) : converte um valor numrico para VARCHAR2. TO_DATE (string): converte um string para data ou hora. TO_NUMBER (string): converte uma string para um valor numrico.

8. Visualizao de valores na tela


Oracle possui vrios pacotes de procedimentos, que podem ser utilizados conforme a convenincia do programador/analista. Um destes pacotes chama-se DBMS_OUTPUT. Ele permite montar uma sada para o usurio. So basicamente trs procedimentos: PUT(conteudo): coloca o conteudo na sada NEW_LINE: imprime a sada, acrescenta uma quebra de linha. PUT_LINE(conteudo): imprime o conteudo, j com a quebra de linha. Apenas um valor pode ser passado como parmetro.

No exemplo abaixo, utiliza-se concatenao para o label mais a varivel. So vrios comandos PUT, concludos com um NEW_LINE. Exemplo:
create or replace procedure lista_vendas(seq number) Is i number(5); nf number(10); dv date; val number(12,2); cursor c1 is

begin open c1; for i in 1..seq loop fetch c1 into nf, dv, val; if c1%found then dbms_output.put('Ordem : ' || i); dbms_output.put(' Nota Fiscal: ' || nf); dbms_output.put(' Data da Venda: ' || dv); dbms_output.put(' Valor: R$'|| val); dbms_output.new_line; else exit; end if; end loop; close c1; end;

select nfiscal, datav, valor from vendas order by valor desc;

A sada deve ser semelhante a:


SQL> exec lista_vendas(10); Ordem : 1 Nota Fiscal: 1011 Data da Venda: 20/08/02 Valor: R$300 Ordem : 2 Nota Fiscal: 1010 Data da Venda: 20/08/02 Valor: R$200 Ordem : 3 Nota Fiscal: 3 Data da Venda: 19/08/02 Valor: R$50 Procedimento PL/SQL concludo com sucesso

Вам также может понравиться