quarta-feira, maio 17, 2006

PowerBuilder - Bloqueando o Teclado

Recentemente precisei bloquear o entrada de dados via teclado de uma aplicação e encontrei a seguinte função:
 
Function long blockinput(BOOLEAN fBlockIt) LIBRARY "user32.dll"
 
onde True bloqueia o teclado e False libera o teclado.

terça-feira, maio 16, 2006

PDA - Sites interessantes

Abaixo estão relacionando alguns sites interessantes para serem acessados nos PDAs:
Abaixo estão relacionados Sites que fornecem informações sobre PDAs e celulares:

Palm – Problemas com o Treo 650

Estamos avaliando a utilização de alguns aparelhos Treo na empresa. Em todos os aparelhos que testamos, a primeira impressão que fica é que o som do telefone é muito ruim.

Este problema ocorre porque existe um Bug no Treo. Para resolvê-lo, você tem que fazer a atualização da ROM do aparelho, que pode ser baixada direto no site da PALM USA (http://www.palm.com/us/support/downloads/treo650updater/).

Após o update, a qualidade do som melhorou muito, mas ainda perde para muitos telefones celulares disponíveis. A solução adotada por vários usuários é a utilização de fones de ouvido bluetooth.

PowerBuilder – Problemas ao retornar valores por output no Oracle

PowerBuilder : 9.0.3 Build 8004
Oracle : 8.1.7.4
Forma de conexão : API O84 Oracle8/8i (8.x.4+)

Recentemente estava tendo erro ao retornar valores VARCHAR2 como OutPut de uma procedure. A definição da minha procedure era :

create or replace PROCEDURE SP_GERA_XML_POS
(p_numcdc cconta.numcdc_cad%type,
p_CodAgente varchar2,
p_CodEmpresa Number,
p_retorno_xml out varchar2) As ...........


No PowerBuilder, criei um UserObject do tipo Transaction e criei uma External Function apontando para o procedure, da seguinte forma:

subroutine SP_GERA_XML_POS(double P_NUMCDC,string P_CODAGENTE,long P_CODEMPRESA,ref string P_RETORNO_XML) RPCFUNC ALIAS FOR "SP_GERA_XML_POS"

Chamei a procedure utilizando seguinte código :

sqlca.sp_gera_xml_pos( 444, 'zzz', 10, xmlretorno)

if sqlca.sqlcode <> 0 then
xmlretorno = sqlca.sqlerrtext
end if

messagebox('teste',xmlretorno)

Este código me retornava a mensagem :
ORA-06502: PL/SQL: numeric or value error: character string buffer too small

Para resolver o problema, descobri que tenho que inicializar a variável que será utilizada para receber o retorno. Como o Oracle possui um limite de 4000 caracteres, alterei o meu código para ficar da seguinte forma:

xmlretorno = space(4000)

sqlca.sp_gera_xml_pos( 444, 'zzz', 10, xmlretorno)

if sqlca.sqlcode <> 0 then
xmlretorno = sqlca.sqlerrtext
end if

messagebox('teste',xmlretorno)

Desta forma, o problema foi solucionado.

quinta-feira, maio 04, 2006

VisualStudio 2005 – Problemas com o Help

Recentemente instalei o VisualStudio 2005 completo com o MSDN completo. Quando tentei abril o MSDN Library for VisualStudio 2005 obtive o seguinte erro:

Microsoft Document Explorer cannot be shown because the specified help collection 'ms-help://MS.MSDNQTR.v80.en' is invalid

Analisei vários sites e fóruns e descobria a origem e como resolver o problema:

Origem
A minha instalação foi feito a partir de uma imagem de DVD (Arquivo .BIN). Para abrir o arquivo .BIN, utilizei o WINRAR e extrai os arquivos para o meu drive local.
Instalei o VisualStudio e nenhum erro foi informado.
De acordo com artigos que li, o problema está na utilização do WINRAR para extrair arquivo do .BIN. Por algum motivo, o WINRAR modifica alguns arquivos, corrompendo-os e causando o erro acima.

Solução.
Instalei a última versão do Software DAEMON TOOLS, que cria um drive virtual para o arquivo BIN, simulando um drive de DVD.
Apenas pedi para corrigir a instalação do MSDN e o mesmo passou a funcionar.

terça-feira, maio 02, 2006

Oracle – Dica de Performance

Recentemente fiz um trabalho em conjunto com um excelente DBA Oracle para analisarmos alguns pontos de baixa performance.

Um dos pontos que mais causou problemas foi o tratamento dado ao desenvolvedores para os parâmetros opcionais.

Por exemplo, vamos dizer que em uma consulta você tem três parâmetros e todos eles são opcionais. Abaixo estou listando as soluções adotadas e o que podemos concluir das mesmas:

1) Passar Nulo no parâmetro não informado
Where ( Campo1 = :Parametro1 or :Parametro1 is null)
And ( Campo2 = :Parametro2 or :Parametro2 is null)
And ( Campo3 = :Parametro3 or :Parametro3 is null)


Nesta solução, se o parâmetro for informado ele é passado para a query, ao contrário passa-se nulo.
Essa é a pior solução que pode ser adotada. O otimizador do Oracle identifica o OR e verifica que a mesma coluna não é utilizada nas duas comparações e por isso não utiliza índice, degradando em muito o tempo de resposta da query.

2) Passar o valor por limite
Where ( Campo1 Between :Parametro1_ini and :Parametro1_fim)
And (Campo2 Between :Parametro2_ini and :Parametro2_fim)
And (Campo3 Between :Parametro3_ini and :Parametro3_fim)


Nesta solução, se o parâmetro for informado, o valor é passado para o parâmetro inicial e final, por exemplo Campo1 between 45 and 45. Ao contrário, é passado um valor de forma a não filtrar os dados, por exemplo Campo1 between 0 and 9999.
Essa solução, apensar de funcionar, deve ser evitada, pois em algumas situações o Oracle armazena o plano de execução para utilizá-lo futuramente, com a intenção de melhorar a performance da query, evitando a analise necessária para identificar o melhor plano. Como os valores passados por limite podem vária, este tipo de query pode prejudicar o trabalho do otimizador.
Além disso, se você passa apenas um parâmetro, você está gerando trabalho extra para o Oracle, que tem que avaliar se os dois outros parâmetros devem ou não ser utilizados pelo filtro.

3) Montar a Query Dinamicamente
Essa é a melhor solução, onde alteramos a query em tempo de execução passando apenas os valores necessários. Dessa forma, o otimizador pode trabalhar com uma query mais simples e montar o plano de execução com mais precisão.

Devo lembrar que em algumas situações, como a utilização de Composites complexas, essa solução não poderá ser adotada. Neste caso, recomendo utilizar a solução B.

Oracle - Query com Recursividade

De vez enquanto recebo um e-mail de como desenvolver uma query com recursividade (Peças de um automóvel, etapas de um projeto, hierarquia de funcionários, etc...). O Oracle possui um comando interessante que recupera o dado recursivamente, independente da quantidade de níveis.

O nome deste comando é CONNECT BY PRIOR

Abaixo estou enviando o trecho do e-mail que um amigo meu enviou sobre este comando:

Pessoal, hoje eu aprendi um recurso interessante do oracle utilizado para trazer um result set com recursividade.
Talvez seja útil para vocês.


SELECT lpad(' ', 2*level) ID ID, NOME, REC_ID FROM RECURSIVIDADE start with id = 3 CONNECT BY PRIOR ID = REC_ID

Escrito por : Wellington Fernandes do Carmo