Banco de Dados - Oracle
PL/SQL - Procedimentos (parte 2)
O corpo de um procedimento é um bloco de pl/sql com seção declarativas, executáveis e de exceções...
por Márcio NovelliO corpo de um procedimento é um bloco de pl/sql com seção declarativas, executáveis e de exceções. A seção declarativa esta localizada entre a palavra-chave IS ou AS e a palavra-chave BEGIN. A seção executável (a única que e obrigatória) esta localizada entre as palavras-chave BEGIN e EXCEPTION. A seção de excepcoes esta localizada entre as palavras-chave EXECPTION e END.
OBS.: NAO EXISTE PALAVRA-CHAVE DECLARE NUMA DECLARACAO DE PROCEDIMENTOS OU DE FUNCAO; EM VEZ DELA E UTILIZADA A PALAVRA-CHAVE IS OU AS.
A estrutura de um procedimento tem o seguinte aspecto:
CREATE OR REPLACE PROCEDURE nome_procedimento AS /* SECCAO DECLARATIVA */ BEGIN /* EXECUTAVEL */ EXCEPTION /* EXECEPCOES */ END nome_procedimento;
Opcionalmente, o nome do procedimento pode ser incluído apos a instrução END final na declaração do procedimento. Se existir um identificador a seguir a END, tem como corresponder ao nome do procedimento. E considerado bom estilo incluir o identificador, visto que enfatiza a instrução END, que corresponde a instrução CREATE.
Restrições aos parâmetros formais
/* A declaração de procedimento seguinte e ilegal e gerada um erro de compilação - illegal */ SET echo off PROMPT Parametro iLegal… SET echo on CREATE OR REPLACE PROCEDURE Parametro ( p_Parametro1 IN OUT VARCHAR2(10), p_Parametro2 IN OUT NUMBER(3,2)) AS BEGIN p_Parametro1 := "marcio_novelli"; p_Parametro2 := 12.3; END Parametro; / show erros /* A declaração de procedimento seguinte e legal - declaração correta abaixo */ SET echo off PROMPT Parametro Legal… SET echo on CREATE OR REPLACE PROCEDURE Parametro ( p_Parametro1 IN OUT VARCHAR2, p_Parametro2 IN OUT NUMBER) AS BEGIN p_Parametro1 := "marcio_novelli"; p_Parametro2 := 12.3; END Parametro; /
Pergunta
Quais são então as restrições a p_Parametro1 e p_Parametro2?
As restrições tem origem nos parâmetros reias. Se chamarmos Parâmetro com
DECLARE v_Variavel1 VARCHAR2(40); v_Variavel2 NUMBER(3,4); BEGIN Parametro(v_Variavel1, v_Variavel2); END; /
p_Parametro1 tera um comprimento Maximo 40 (tendo origem no parâmetro real v_Parametro1) e p_Parametro2 tera precisão 3 e escala 4 (tendo origem no parâmetro real v_Parametro2). É importante estar consciente deste fato. Considere o seguinte bloco,que também chama Parametro
DECLARE v_Variavel1 VARCHAR2(10); v_Variavel2 NUMBER(3,4); BEGIN Parametro(v_Variavel1, v_Variavel2); END; /
A única diferença entre este bloco e o anterior e que v_Variavel1,e conseqüentemente p_Parametro1, tem um comprimento de 10 em vez de 40.
Visto que Parâmetro(nome do procedimento) atribui uma cadeia de caracter com um comprimento de (MARCIO NOVELLI) 14 VARCHAR2(e conseqüentemente v_Variavel1) nao existe espaço suficiente na cadeia .Isto ocorrera um erro Oracle quando o procedimento for chamado:
ORA-6502: NUMERIC OR VALUE ERROR
OBS: PARA EVITAR ERROS COMO ORA-6502, DOCUMENTE TODOS OS REQUISITOS DE RESTRICOES DOS PARAMETROS REAIS QUANDO O PROCEDIMENTO FOR CRIADO. ESTA DOCUMENTACAO DEVE SER CONSTITUIDA POR COMENTARIOS ARMAZENADOS COM O PROCEDIMENTO E DEVE INCLUIR UMA DESCRICAO DO QUE E EFETUADO PELO PROCEDIMENTO,PARA ALEM DE QUAISQUER DEFINICOES DE PARAMETROS
%TYPE e parâmetros de procedimento - A única forma de restringir um parâmetro formal e utilizando %TYPE.Se um parâmetro formal for declarado com %TYPE e o tipo subjacente for restringido, a restrição aplica-se-a ao parâmetro formal e nao ao parâmetro real. Se declararmos Parâmetro com:
CREATE OR REPLACE PROCEDURE Parametro ( p_Parametro1 IN OUT VARCHAR2, p_Parametro2 IN OUT estudantes.credito%TYPE) AS BEGIN p_Parametro2 := 12345; END Parametro; / /* CREATE TABLE estudantes ( Numero_id NUMBER(5) PRIMARY KEY, nome VARCHAR2(20), sobre_nome VARCHAR2(20), curso VARCHAR2(30), credito NUMBER(3) ); */
p_Parametro2 será restringido com precisão 3, visto que é a precisão da coluna credito. Mesmo que chamemos Parâmetro(procedure) com um parâmetro real que tenha a precisão adequada,e a precisão formal que prevalece.
SET echo off PROMPT Chamando parametro Ilegal (ORA-6502)... SET echo on DECLARE v_Variavel1 VARCHAR2(1); v_Variavel2 NUMBER; BEGIN . . Parametro(v_Variavel1, v_Variavel2); END; /
Nota: acima dará origem ao erro ORA-6502.
Notação nomeada e posicional
Em todos os códigos (exemplos) citados acima , os argumentos reais estão associados aos argumentos formais pela posição . Dada uma declaração do procedimento como:
CREATE OR REPLACE PROCEDURE Notacao ( p_ParametroA VARCHAR2, p_ParametroB NUMBER, p_ParametroC BOOLEAN, p_ParametroD DATE) AS BEGIN NULL; END Notacao; /
e um bloco de chamada como:
DECLARE v_Variavel1 VARCHAR2(10); v_Variavel2 NUMBER(7,6); v_Variavel3 BOOLEAN; v_Variavel4 DATE; BEGIN Notacao(v_Variavel1, v_Variavel2, v_Variavel3, v_Variavel4); END; /
Os parâmetros reais estão associados aos parâmetros formais pela posição: v_variavel1 esta associado a p_ParametroA , e assim sucessivamente. Isto e designado por notação posicional.
Notação Posicional
A notação posicional e mais utilizada e também e a notação utilizada em outras linguagens da terceira geração, tais como C.
Em alternativa, podemos chamar o procedimento utilizando a notação nomeada:
DECLARE v_Variavel1 VARCHAR2(10); v_Variavel2 NUMBER(7,6); v_Variavel3 BOOLEAN; v_Variavel4 DATE; BEGIN Notacao(p_ParametroA => v_Variavel1, p_ParametroB => v_Variavel2, p_ParametroC => v_Variavel3, p_ParametroD => v_Variavel4); END; /
Geralmente utilizo a notação posicional, porque prefiro escrever código sucinto. Porém é importante utilizar bons nomes para os parâmetros reais. Por outro lado, se o procedimento aceitar um grande numero de argumentos, e desejável utilizar a notação nomeada, visto que e mais fácil corresponder os parâmetros formais e reais. Contudo, os parâmetros com tantos argumentos são relativamente raros.
Um forte abraço a todos, e até o próximo artigo!