TDBXReader e NULL

Delphi

09/07/2012

Galera,
Estou com um probleminha aqui que nao sei se é um BUG do TDBXREADER ou alguma falha minha:

Tenho uma consulta que retorna o seguinte:
ID IDPAC
24 NULL
26 NULL
27 4994
28 NULL
29 NULL

Mas quando executo essa consulta usando um TDBXReader, os resultados que ele me traz sao os seguintes:
ID IDPAC
24 NULL
26 NULL
27 4994
28 4994
29 4994

É como se ele não limpasse o buffer a cada campo lido, então, no proximo campo, se determinado valor for nulo ele mantem o valor lido anteriormente.

Estou lendo os dados dessa forma:
While DBXREADER.NEXT
BEGIN
id :=  dbxreader.Value[idagenda].AsString
idpac := dbxreader.Value[idpac].asint32);
END

Alguem tem ideia do que pode ser isso?
Cleidson Silva

Cleidson Silva

Curtidas 0

Respostas

Cleidson Silva

Cleidson Silva

09/07/2012

E mais um detalhe:
Se eu fizer um teste do tipo:

dbxreader.Value[idpac].isnull

Ele retorna true para esses dois ultimos registros.

Eu sei que posso resolver isso facilmente se colocar na instrucao sql algo do tipo:
select coalesce(idpac,0)

Mas isso é algo sério, que pode gerar resultados desastrosos em uma consulta.
GOSTEI 0
Marco Salles

Marco Salles

09/07/2012

bem eu não sei como vc esta utilizando a consulta , mas pq vc não tenta utilizando o asinteger mesmo

idpac := dbxreader.Value[idpac].asinteger);

estou falando isto porque estou com um problema issoluvel na multiplocação de dois valores do tipo int64 e o resultado
fica negativo quando os valores utilizados estão dentro da faixa permitido para este Type

[]sds
GOSTEI 0
Cleidson Silva

Cleidson Silva

09/07/2012

Marco,
Já tentei isso mas o erro persiste.
Tentei inclusive, executar e chegar o resultado no proprio server e o resultado continua o mesmo. Estou achando que isso pode ser um BUG do DBEXPRESS.

Só funciona direito quando retorno a consulta através de uma TSQLQUERY.
Mas ainda não sei como executar uma SQLQUERY no cliente, usando a conexao ao banco que está no servidor.
Alguma dica quanto a isso?
GOSTEI 0
Deivison Melo

Deivison Melo

09/07/2012

Imagino que essa ordenação seja devido ao tipo de dado utilizado internamente para a consulta.

Digamos que vc faz uma instrução sql e deseja ordenar os valores consultados, mas o campo que armazena os valores
númericos é um campo alphanúmerico então sua ordenação ficaria:

Instrução SQL:

select codigo from pedidos
order by codigo

1
10
2
20
3
30


ao invés de

1
2
3
10
20
30

Isso devido ao campo código ter seu tipo varchar(nvarchar) ao invés de ser um number ou integer (int no seu caso). Pois quando guardamos os valores númericos em campos alphanumericos e mandamos ordenar eles ficaram ordenados dessa forma. O que estou achando que ocorreu com seu código, quando falo isso estou me referindo ao âmbito de sistema e não de banco. Vc deveria utilizar tratar como número e não como cadeia de caracteres (como o amigo acima já sugeriu).

Bom, espero ter ajudado, qualquer coisa estou por aqui!


GOSTEI 0
Cleidson Silva

Cleidson Silva

09/07/2012

Deivison,

Como eu disse acima, mesmo tratando como asInteger dá na o mesmo erro.
Só da certo se uso um TSQLQUERY ao inves do DBXREADER.
GOSTEI 0
Deivison Melo

Deivison Melo

09/07/2012

Pq acha que o coalesce (nvl, decode e etc) pode ser desastrosos no seu código?

GOSTEI 0
Cleidson Silva

Cleidson Silva

09/07/2012

Bem,
Não é o coalesce que é catastrófico.
Eu disse no sentido de usar o coalesce para resolver esse problema aqui e deixar outras consultas por conta do dbxreader, correndo o risco dele retornar esses dados inválidos como está fazendo agora.
Imagine se ele trouxer um valor qualquer pra cada vez que tiver um valor null num campo.
GOSTEI 0
Deivison Melo

Deivison Melo

09/07/2012

Isso vai depender da sua codificação, aqui usamos nvl e nvl2(e tb o decode, pois usamos oracle) para tratar valores nulos em query´s e não temos problemas (e olhe que trabalho com sistemas hospitalares enormes (ERP Hospitalar). O q pode afetar é a performance de sua aplicação, mas isso também pode ser burlado se ao fizer sua query ir testando e vendo o plan sort (tempo que a query leva para apresentar as informações (resultset).
GOSTEI 0
Cleidson Silva

Cleidson Silva

09/07/2012

Concordo com voce que fazendo algumas simples verificacoes da pra contornar o problema. Só que isso parece ser um erro do dbexpress. Então, talvez ao invés de ter que fazer verificacoes desse tipo no codigo inteiro, seria mais lógico se apenas conseguisse fazer a consulta funcionar da maneira correta não acha?
GOSTEI 0
Deivison Melo

Deivison Melo

09/07/2012

Multas vezes para fazermos as consultas funcionarem da forma que desejamos temos que usar de expertise na codificação, não digo para vc fazer uma gambiarra (não que não possa, as vezes elas nos salvam), mas entendo que vc quer ver se isso não seria um erro ou bug do componente. Se vc tem realmente tempo para ficar pesquisando por isso e não quer as soluções quem propomos para vc então boa sorte, espero que consiga o que está buscando e depois venha ao forum e poste a solução encontrada para que assim podermos ajudar outros usuários.

Qualquer coisa estou por aqui! Para me chamar basta perguntar no forum!!

Abração!!
GOSTEI 0
Marco Salles

Marco Salles

09/07/2012

Vc consegue fazer um dpr simples contendo ua pequena tabela onde possamos simular o seu erro e tentarmos achar um solução o

dá para fazer isto ?? coisa simples
GOSTEI 0
Deivison Melo

Deivison Melo

09/07/2012

O colaborador acima fez uma ótima sugestão!

Faça isso que a pessoa que conseguir mais rápido disponibilidade para ajudar, tenha certeza que vai ajudar!
GOSTEI 0
Cleidson Silva

Cleidson Silva

09/07/2012

Pronto,

Está ai o exemplo:
https://dl.dropbox.com/u/24767444/DBXREADER2.zip
GOSTEI 0
Cauê Nishijima

Cauê Nishijima

09/07/2012

Cleidson e se usar GetString e GetInt32 ao inves de AsString e AsInt32...Estou sem o Delphi aqui, mas amanhã no serviço posso ver qual é o problema pra você.

Abraços
Cauê Nishijima
GOSTEI 0
Marco Salles

Marco Salles

09/07/2012

enviei um email para você

Recebeu ???
GOSTEI 0
Eduardo Silva.

Eduardo Silva.

09/07/2012

Bom, esse erro(bug) foi reportado em 2011 em:
http://qc.embarcadero.com/wc/qcmain.aspx?d=93247

Assim como esse, existe outros também na QualityCentral e acredito que ainda não foi corrido.

Você pode fazer algo do tipo:

procedure TForm1.Button1Click(Sender: TObject);
var
r: tdbxreader;
cmd: TDBXCommand;
Result, txt: string;
begin
Conecta;
cmd := conn.DBXConnection.CreateCommand;
try
try
cmd.Text := select * from CLIENTES;
r := cmd.ExecuteQuery;
while r.Next do
begin
if r.Value[IDTESTE].IsNull then
Result :=
else
Result := r.Value[IDTESTE].AsString;

txt := format(ID: %d Nome: %s Telefone: %s IDTESTE: %s,
[r.Value[ID].AsInt32, r.Value[NOME].AsString,
r.Value[TELEFONE].AsString, Result]);
ListBox1.Items.Add(txt);
end;
except
on e: exception do
showmessage(e.Message);
end;
finally
cmd.Free;
r.Free;
conn.Close;
conn.Free;
end;

Boa Sorte!

Eduardo Belo
GOSTEI 0
Cleidson Silva

Cleidson Silva

09/07/2012

enviei um email para você

Recebeu ???


Recebi sim Marco,
Mas pelo que nos mostrou ai o Eduardo, esse é um bug já conhecido mesmo.

Só esperar então a Embarcadero resolver.

Obrigado a todos pela cooperação!!
GOSTEI 0
POSTAR