diversos sobre oracle
TRANSCRIPT
Utilizando imagens no forms 6i.
Manipular imagens no Oracle Forms. Para isso, utilizaremos a procedure READ_IMAGE_FILE, nativa do forms. Sua definição é: Sintaxe PROCEDURE READ_IMAGE_FILE (file_name VARCHAR2,file_type VARCHAR2,item_id ITEM);
PROCEDURE READ_IMAGE_FILE (file_name VARCHAR2,file_type
VARCHAR2,item_name VARCHAR2);
Parametros
file_name Nome do arquivo de imagem, se passado apenas o nome irá buscar o
caminho default da Path, também é possível passar o caminho completo.
file_type Tipo do arquivo: BMP, CALS, GIF, JFIF, JPG, PICT, RAS, TIFF, ou TPIC.
item_id Id do item que irá receber um a imagem.
item_name Nome do item que irá receber a imagem.
Bom, vamos aos passos para a construção do form.
1 - Vamos criar um data block, não base table (aquele que não referencia a estrutura de
um objeto do banco de dados) com nome de IMAGEM.
2 - Entre na propriedade do data block, altere o valor da opção DATABASE DATA
BLOCK para NO. Afinal, este bloco não precisa acessar o banco de dados.
3 - Neste data block, criaremos dois campos.
São eles:
IMAGEM do tipo Image
CAMINHO do tipo TEXT ITEM
4 - Devemos criar um canvas chamado Imagem.
5 - Depois de criado, alterar os campos para que ficam dentro dele.
Para isso entre na propriedade do campo, e na opção canvas escolha IMAGEM.
Faça isso para os dois campos.
6 - Após isso entre no Layout Editor [F2] e posicione os campos da melhor forma
7 - Agora, vamos criar um procedure com o nome de LEIMAGEM.
Com o conteúdo:
PROCEDURE leImagem(p_imagem varchar2) IS
button_pressed number;
alerta Alert;
begin
:SYSTEM.MESSAGE_LEVEL := 25;
IF(:IMAGEM.CAMINHO IS NOT NULL)THEN
READ_IMAGE_FILE(p_imagem,’BMP’,'IMAGEM.IMAGEM’);
END IF;
IF NOT FORM_SUCCESS THEN
alerta := find_alert(’ERRO’);
button_pressed := SHOW_ALERT(alerta);
END IF;
:SYSTEM.MESSAGE_LEVEL := 0;
END;
Esta deverá ser chamada quando houver uma alteração no campo CAMINHO, vamos
colocar no WHEN-VALIDATE-ITEM a chamada para esta procedure. Optei de criar
nesta trigger pois é apenas quando mudar o conteúdo deste campo que a imagem será
recarregada.
8 - Vamos criar a trigger WHEN-VALIDATE-ITEM no campo CAMINHO com
conteúdo:
declare
begin
leImagem(p_imagem => :IMAGEM.CAMINHO);
end;
É legal observar que o Oracle possibilita dois tipos de passagem de parâmetros, são
eles:
• O habitual posicional onde os parâmetros são passados na mesma seqüência que
declarados.
Exemplo: leImagem(:IMAGEM.CAMINHO);.
• E o referenciado onde os parâmetros são passados com a referencia identificada.
Exemplo: leImagem(p_imagem => :IMAGEM.CAMINHO);.
9 - Agora vamos criar um alerta para tratar a exceção, pois é possível que o usuário
digite um caminho que não há uma imagem.
Vamos mudar algumas propriedades:
10 - No alert ERRO:
Title: Erro ao Encontrar a Imagem
Message: Imagem não encontrada!
Deixe a propriedade Button 2 Label em branco, utilizaremos apenas o botão OK no
alert.
11 - Na Window WINDOW1:
Title: Imagem
No campo CAMINHO:
Maximum Length: 120
12 - Compile todo o form [Ctrl + Shift + K].
13 - Execute o forms [Ctrl + R] e se divirta.
Visão inicial do programa ao ser executado.
Visão do programa com a imagem encontrada.
Visão do programa com a imagem não encontrada.
Validando diversos campos no Oracle Forms 6i Existem alguns Forms que pelo seu tempo de vida e diversas correções e implementações de
novas regras de negócio fazem com que um único Forms contenha as funções e complexidades
de um sistema completo (já operei com um Forms que o arquivo fonte .FMB tinha 10 Mb).
Um Forms desse tipo com certeza terá diversos campos, e estes campos por sua vez deverão
conter validações e consistências com o intuito de manter e assegurar que os dados inseridos
pelos usuários são os corretos ou na pior das situações o menos errado possível.
E deixar o código-fonte do seu PL/SQL embutido no Forms completamente abarrotado de IF´s
para realizar essas consistências, realmente não é o melhor caminho, pois torna a manutenção
maçante e lenta, além de deixar o seu código “feio”.
Veja um exemplo, de como consistir campos de forma inteligente e elegante, dando
simplicidade e agilidade tanto no desenvolvimento quanto na manutenção do código-fonte
PL/SQL: /* ************************************************************************************************** * Autor: Petter Rafael * Empresa: Viamais Web Intelligence * Desde: Dezembro/2010 * Versão: 1.0.1 – Oracle Forms 6i / Oracle PL/SQL 8 * * Objetivo: Consistir blocos de dados no Forms de forma automática e funcional, eliminando a * necessidade de construção de procedures e outros artefatos para consistir diversos * campos. Ideal para blocos de dados com grande quantidade de campos. * * Variáveis: p_nome_bloco = Nome do bloco que será consistido. * p_tipo_valida = Tipo de consistência que será realizada. * 1 - para consistência de campos nulos. * 2 - para consistência de campos negativos. * p_campo_tipo = Tipo do campo que será consistido. Obs.: precisar ser idêntico à nomenclatura do Forms (consulte F1 para ajuda). * p_mens_err_pro = Identifica se q mensagem de erro padrão será substituída por uma mensagem de erro definida pelo desenvolvedor. * p_mensagem_erro = Texto da mensagem de erro própria. Somente será preenchido caso a mensagem de erro personalizada esteja ativa. * p_cor_erro = Cor que o fundo do campo deve assumir caso sinalize inconsistência. Caso esteja nulo uma cor padrão é assumida. Padrão de cores Forms (consulte F1 para ajuda). * * Retorno: Retorna mensagem de erro caso os critérios indiquem inconsistência informando o * HINT do campo para sinalizar para o usuário qual campo precisa ser corrigido. * Alterar a cor de fundo (background) do campo caso possível. ************************************************************************************************* */
PROCEDURE C_CONSIS_GERAL(p_nome_bloco IN varchar2
,p_tipo_valida IN NUMBER
,p_campo_tipo IN varchar2
,p_mens_err_pro IN BOOLEAN
,p_mensagem_erro IN varchar2
,p_cor_erro IN varchar2) IS
w_campo_fim varchar2(400);
w_campo_ini varchar2(400);
w_erro varchar2(4000);
w_cor_back varchar2(15) := 'r350g0b0';
BEGIN
-- Controle da mensagem de erro.
IF p_mens_err_pro = TRUE THEN
w_erro := p_mensagem_erro;
ELSE
w_erro := 'Os seguintes campos estão com erros: ';
END IF;
-- Controle para cor de background de campos consistidos
IF p_cor_erro IS NOT NULL THEN
w_cor_back := p_cor_erro;
END IF;
-- Resgatando dados para início da consistência.
w_campo_ini := get_block_property(p_nome_bloco, first_item);
w_campo_fim := get_block_property(p_nome_bloco, last_item);
go_item(p_nome_bloco || '.' || w_campo_ini);
loop
-- Somente atua sobre campos de tipo específico
IF get_item_property(:system.cursor_item, item_type) = p_campo_tipo THEN
IF p_tipo_valida = 1 THEN
IF :system.current_value IS NULL THEN
message(w_erro || get_item_property(:system.cursor_item, hint_text));
set_item_property(:system.cursor_item, background_color, w_cor_back);
END IF;
elsif p_tipo_valida = 2 THEN
IF :system.current_value < 0 THEN
message(w_erro || get_item_property(:system.cursor_item, hint_text));
set_item_property(:system.cursor_item, background_color, w_cor_back);
END IF;
END IF;
END IF;
-- Saída caso alcance o último campo do bloco
IF w_campo_fim = :system.current_item THEN
exit;
END IF;
next_item;
END loop;
END;
Como utilizar? É muito simples, no Forms crie uma procedure (Program units) e cole o código PL/SQL que listei
acima.
Pronto, agora é só chamar a procedure, passando os parâmetros de acordo com a sua necessidade. Pode ser utilizada a
partir de qualquer triggers do Forms ou ainda embutida em outra procedure ou function.
As principais vantagens são:
Código PL/SQL embutido no Forms, mais coeso, simples de ser mantido e/ou alterado;
Maior eficiência, pois trata a consistência orientada por tipo do campo e validação e não caso a caso como
normalmente vemos;
Maior agilidade no desenvolvimento é mais versátil;
Permite customizar a mensagem de erro por campo, de forma transparente para o desenvolvedor, sem a
necessidade de alterar código-fonte PL/SQL;
Testada no Oracle Forms 6i, porém não existem restrições para versões posteriores do Forms.
mar/11
24
Falha de segurança no PL/SQL Developer afeta OracleTodo bom DBA, AD ou mesmo qualquer analista de sistemas e/ou programador sabe que a senha dos usuários com privilégios máster de um determinado banco de dados deve ser muito bem guardada. Porém notei um comportamento muito estranho no PL/SQL Developer, uma das ferramentas mais utilizadas para quem trabalha com Oracle. Supondo que o DBA utilize o PL/SQL Developer para seus trabalhos, como logicamente ou ele terá a senha do SYSDBA ou pelo menos um usuário com mais privilégios ele irá utilizar este usuário no PL/SQL Developer, feito isso, dentro da pasta Preferences irá ser armazena seu perfil de uso, em um arquivo criptografado. Os arquivos de devem ser copiados são: default.ini e user.prefs. Qual o problema? Se o arquivo é criptografado quem tentar abri-lo não vai conseguir decifrar a senha. Porém, eu posso copiar o perfil de uso utilizado pelo DBA e simplesmente copia-lo para dentro da pasta Preferences do meu PL/SQL Developer, assim eu poderei utilizar a senha do usuário do DBA e terei os mesmos privilégios. Simples assim. Creio eu que o pessoal que desenvolve o PL/SQL Developer poderia pelo menos colocar uma validação para ver se o usuário da pasta Preferences é o mesmo do usuário informado dentro do arquivo. Embora a senha de alto privilégio continue indecifrável um usuário mal intencionado poderá conseguir acesso privilegiado ao banco de dados Oracle, efetuar o que ele quiser e a culpa ainda ficará com a pessoa que utiliza o usuário roubado.
Descobrindo a semana com PL/SQL
Talvez você ainda não tenha precisado ou talvez nem saiba, mas em todo calendário
temos uma informação que não é muito utilizado no cenário brasileiro, é o número da
semana. Começando obviamente a contar da primeira semana do ano, esse número
pode auxiliar bastante se a precisão de cálculo de data do seu não pode ser diária ou
mensal e sim semanal (já trabalhei em diversos sistemas de agenciamento de fretes
que utilizam a semana para montagem de cargas, pois em termos de transporte a
precisão diária é demasia e a precisão mensal é obsoleta demais).
Em PL/SQL, realizar esse procedimento é muito simples, veja o exemplo abaixo:
SELECT to_char(to_date('02-feb-2011'), 'WW') FROM dual
E como retorno eu obtive o número 05, que significa que a data informada é da quinta
semana do ano de 2011.
É claro que a formatação da instalação do seu banco de dados Oracle pode influenciar
um pouco no PL/SQL que passei, por exemplo, o formato de data 02-feb-2011 é o
formato norte-americano, mas poderia ser também o mais usual no Brasil que é
02/02/2011.
Goto no PL/SQL
Noto que alguns programadores/desenvolvedores tem certa repulsa pelo comando
GOTO (vá para, em tradução livre) seja de qual for à linguagem, talvez esse sentimento
seja antigo, pois algumas linguagens de outros tempos permitiam uma verdadeira salada
com o comando GOTO o que tornava a manutenção do código ou alguma melhoria um
verdadeiro trabalho Herculano.
Porém se o código-fonte for bem estruturado, é totalmente passível e de bom tom
utilizar o comando GOTO quando a linguagem o possuir (obviamente).
Não sei se é endêmico da região em que trabalho, mas o pessoal do PL/SQL daqui não
utiliza muito o GOTO em seus softwares, quando é preciso fazer algum jump para
outra parte do código-fonte ou é tudo separado em diversas procedures dentro de um
mesmo body (package) o que pode gerar uma confusão maior do que com o uso do
GOTO, ou o que é pior, fica uma parte do código-fonte dentro de um if e a outra parte
dentro do else, nem preciso comentar muito, veja o resultado por você mesmo:
IF varTeste = TRUE THEN
-- Todo o seu código que será executado caso a condição seja
verdadeira
ELSE
-- Todo o seu código que será executado caso a condição não seja
verdadeira
END IF;
Em pequenos fragmentos de código-fonte isso não trás problemas, mas experimente
dividir o seu código em duas partes, cada uma com mais de 2.000 linhas e veja que isso
fica muito boçal. Agora veja a diferença com o uso do GOTO:
IF varTeste != TRUE THEN
GOTO EXEC
END IF;
-- Todo o seu código que será executado caso a condição seja
verdadeira
<<exec>>
-- Todo o seu código que será executado caso a condição não seja
verdadeira
Fica muito mais fácil de manter e mais performático também. Realmente não sei para
que não utilizar. Ainda duvida da aplicação do GOTO no PL/SQL, veja um exemplo
mais conciso:
DECLARE
w_teste varchar2(1000);
w_laco varchar2(10);
cursor u_teste IS
SELECT cod_venda
FROM vendas
WHERE ;
BEGIN
OPEN u_teste;
loop
fetch u_teste INTO w_laco;
exit WHEN u_teste%notfound;
IF w_teste IS NULL THEN
w_teste := w_laco;
ELSE
w_teste := w_teste || ', ' || w_laco;
END IF;
END loop;
IF w_teste IS NULL THEN
GOTO sem_erro;
END IF;
close u_teste;
dbms_output.put_line('Saída de teste:');
dbms_output.put_line('Valor: ' || w_teste);
<<sem_erro>>
dbms_output.put_line('Fim de execução!');
END;