Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-10-2003
Giniromero Giniromero is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid
Posts: 296
Poder: 22
Giniromero Va por buen camino
problemas al pasar un código SQL al selectSQL

Hola,

Uso delphi 6, interbase 7, dialecto3.

Estoy intentando usar el siguiente código SQL, en un IBDataSet.


Cita:
select NUMALU,SUM(0 - econo.impdebe + econo.imphaber) IMPORTE
from econo
WHERE NUMALU =:alumnos.numalu
GROUP BY NUMALU
ORDER BY NUMALU

Se lo estoy intentando pasar de la siguiente forma:

Cita:
TRY
dbPos := FrmDmodule.TbEcono.Getbookmark;
FrmDmodule.TbEcono.Disablecontrols;
FrmDModule.TbEcono.Close;
//borramos el contenido de la propiedad SelectSQL
FrmDModule.TbEcono.SelectSQL.Clear;
//le asignamos el SQL que tenía al inicio la tabla
FrmDModule.TbEcono.SelectSQL.Add('select NUMCLI, SUM(0 - econo.impdebe + econo.imphaber) IMPORTE');
FrmDModule.TbEcono.SelectSQL.Add('from econo');
FrmDModule.TbEcono.SelectSQL.Add('WHERE NUMCLI =:NUMCLI’);
FrmDModule.TbEcono.SelectSQL.Add('GROUP BY NUMCLI’);
FrmDModule.TbEcono.SelectSQL.Add('ORDER BY NUMCLI ');
FrmDModule.TbEcono.Open;
nAux2 := FrmDModule.TbEconoIMPORTE.value;


lblSaldo.Caption := formatFloat('#,##0.00 €',nAux2);
FINALLY

FrmDmodule.TbEcono.GotoBookmark(dbPos);
FrmDmodule.TbEcono.FreeBookmark(dbpos);
FrmDmodule.TbEcono.EnableControls;
END;


El problema es que al compilar me da fallo, por que me pide unos campos que necesito tener declarados en la tabla, pero que aquí no se como incluir.

¿alguna idea?

Muchas gracias a todos por la ayuda.

Virginia
__________________
Sonrie al mundo, y el mundo te sonreirá :)
Responder Con Cita
  #2  
Antiguo 17-10-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 22
andres1569 Va por buen camino
Hola:

Si te da fallo al compilar, supongo que el error estará en la línea:

nAux2 := FrmDModule.TbEconoIMPORTE.value;

puesto que ese campo TbEconoIMPORTE no lo tienes definido desde Delphi. Para evitarlo, prueba a usar el método, FieldByName de la tabla en cuestión. El compilador no protestará, sólo saltará un error en ejecución si no se halla dicho campo en el Dataset correspondiente:

nAux2 := FrmDModule.TbEcono.FieldByName('IMPORTE').value;

Un saludo
__________________
Guía de Estilo
Responder Con Cita
  #3  
Antiguo 18-10-2003
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 25
__cadetill Va por buen camino
Cita:
Posteado originalmente por andres1569
puesto que ese campo TbEconoIMPORTE no lo tienes definido desde Delphi
bueno, no estoy totalmente de acuerdo con esto, ya que sí podría (y digo podría) tenerlo definido en Delphi.

Si no es éste el error, sería bueno que Virginia digera en que linea le da el error y cual es el error que le da
Responder Con Cita
  #4  
Antiguo 22-10-2003
Giniromero Giniromero is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid
Posts: 296
Poder: 22
Giniromero Va por buen camino
Hola,

Cita:
Si te da fallo al compilar, supongo que el error estará en la línea:

nAux2 := FrmDModule.TbEconoIMPORTE.value;
tenía declarado el campo IMPORTE como campo calculado en la tabla, pero, efectivamente, con esto, que me comentaste,

Cita:
nAux2 := FrmDModule.TbEcono.FieldByName('IMPORTE').value;
no necesito declararlo, cosa que prefiero.

En cuanto al error que me da, es como si en este procedure buscase campos, que tengo declarados en el IDDataSet, que son de la tabla, pero que en este caso no necesito, y no he declarado en el select del SQL.

Por ejemplo. El campo ASIENTO, lo tengo declarado en la tabla econo.

Si le paso a la propiedad SelectSQL con el código,


quote:
--------------------------------------------------------------------------------

TRY
dbPos := FrmDmodule.TbEcono.Getbookmark;
FrmDmodule.TbEcono.Disablecontrols;
FrmDModule.TbEcono.Close;
//borramos el contenido de la propiedad SelectSQL
FrmDModule.TbEcono.SelectSQL.Clear;
//le asignamos el SQL que tenía al inicio la tabla
FrmDModule.TbEcono.SelectSQL.Add('select NUMCLI, SUM(0 - econo.impdebe + econo.imphaber) IMPORTE');
FrmDModule.TbEcono.SelectSQL.Add('from econo');
FrmDModule.TbEcono.SelectSQL.Add('WHERE NUMCLI =:NUMCLI’);
FrmDModule.TbEcono.SelectSQL.Add('GROUP BY NUMCLI’);
FrmDModule.TbEcono.SelectSQL.Add('ORDER BY NUMCLI ');
FrmDModule.TbEcono.Open;
nAux2 := FrmDModule.TbEcono.FieldByName('IMPORTE').value;


lblSaldo.Caption := formatFloat('#,##0.00 €',nAux2);
FINALLY

FrmDmodule.TbEcono.GotoBookmark(dbPos);
FrmDmodule.TbEcono.FreeBookmark(dbpos);
FrmDmodule.TbEcono.EnableControls;
END;


--------------------------------------------------------------------------------
No estoy incluyendo dicho campo en la la consulta SQL, y me resulta el siguiente error:


Cita:
Project xxx raised exception class EDatabaseError with message 'TbEcono: Field 'ASIENTO' not found
He estado viendo posibles formas de añadir, en la consulta sql , estos campos que me va pidiendo, pero si los añado a la consulta, esta queda mucho más complicada, y no me devuelve un registros, como hace esta, sino varios, lo cual no me interesa.

¿Hay alguna manera de que no me los pida?

Tal vez todo esto tenga que ver con que estoy trabajando con un DataModule en el que tengo un IBDataSet, TbEcono, al que le cambio el código del selectSQL, cuando quiero cambiar de consulta , en vez de crearme otro IBDataSet nuevo, para la nueva consulta.

De este IBDataSet tira un DBGrid, (por eso necesito tener declarados los campos), y a la vez pretendo que me haga, de un modo puntual, estas consultas que os he puesto, para que me calcule si el usuario debe dinero o no.

Muchas gracias por todo,

Saludos,

Virginia
__________________
Sonrie al mundo, y el mundo te sonreirá :)
Responder Con Cita
  #5  
Antiguo 22-10-2003
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 25
__cadetill Va por buen camino
Hola Virginia

Por lo que entiendo de tu explicación, este TIBDataSet tiene campos persistentes declarados, cierto? Si es así, la consulta SQL que lances en él, deberá devolver esos campos, ni más ni menos.

Si no puedes omitir la declaración de los campos persistentes y, sólo necesitas lanzar este tipo de SQL de vez en cuando, te propongo 2 alternativas

1.- Pones un TIBQuery en el DataModule sin campos persistentes y, en él lanzas las consultas SQL (temporales) que necesites en cada momento.

2.- Dependiendo el diseño de la aplicación, la opción 1 no será válida, por lo que, esta segunda opciónsería la que convendría. Ésta es, crear tu misma el componente en ejecución de forma local al procedimiento o función (es la que yo utilizo para evitarme posibles errores)

Código:
procedure ElQueSea;
var
  Q : TIBQuery;
begin
  Q := TIBQuery.Create(Self);
  Q.Database := MyDataBase;
  try
    // lanzo la consulta SQL que necesite 
  finally
    FreeAndNil(Q);
  end;
end;
Espero te sirva
Responder Con Cita
  #6  
Antiguo 22-10-2003
Giniromero Giniromero is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid
Posts: 296
Poder: 22
Giniromero Va por buen camino
Hola,

Cita:
Por lo que entiendo de tu explicación, este TIBDataSet tiene campos persistentes declarados
Efectivamente, ese es "el mio problema".

He probado el código que me comentas,

code:--------------------------------------------------------------------------------
procedure ElQueSea;
var
Q : TIBQuery;
begin
Q := TIBQuery.Create(Self);
Q.Database := MyDataBase;
try
// lanzo la consulta SQL que necesite
finally
FreeAndNil(Q);
end;
end;
--------------------------------------------------------------------------------

Lo tengo de la siguiente forma en mi procedure,

Cita:

Procedure TFrmFxMain.CalculaSaldo;
var nAux2: integer;
var Q : TIBQuery;
begin

nAux2:=0;
Q := TIBQuery.Create(Self);
Q.Database := FrmDmodule.TbEcono.Database;

TRY

Q.Disablecontrols;
Q.Close;
//borramos el contenido de la propiedad SelectSQL
Q.SQL.Clear;
//le asignamos el SQL que tenía al inicio la tabla
Q.SQL.Add('select NUMALU, SUM(0 - econo.impdebe + econo.imphaber) IMPORTE');
Q.SQL.Add('from econo');
Q.SQL.Add('where NUMALU =:NUMALU ');
Q.SQL.Add('GROUP BY NUMALU ');
Q.SQL.Add('ORDER BY NUMALU ');
Q.Open;
nAux2 := Q.FieldByName('IMPORTE').Value;


lblSaldo1.Caption := formatFloat('#,##0.00 €',nAux2);
FINALLY

Q.EnableControls;
FreeAndNil(Q);
END;
end;
Pero me devuelve el siguiente mensaje de error:

Cita:
Invalid variant type conversion
Por lo que he podido ver, es algo relativo al paso del valor del campo importe, a la variable nAux2, pues si pongo un breakpoint, me da el error tras ejecutar:

nAux2 := Q.FieldByName('IMPORTE').Value;

Si en vez de poner .Value, pongo .asvariant, o .asinteger también me da error.



¿Podría ser que necesita que el campo "IMPORTE" sea un campo persistente?

Gracias por la ayuda.

Virginia
__________________
Sonrie al mundo, y el mundo te sonreirá :)
Responder Con Cita
  #7  
Antiguo 22-10-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Posteado originalmente por Giniromero
Pero me devuelve el siguiente mensaje de error:

Invalid variant type conversion

Por lo que he podido ver, es algo relativo al paso del valor del campo importe, a la variable nAux2, pues si pongo un breakpoint, me da el error tras ejecutar:

nAux2 := Q.FieldByName('IMPORTE').Value;

Si en vez de poner .Value, pongo .asvariant, o .asinteger también me da error.

¿Podría ser que necesita que el campo "IMPORTE" sea un campo persistente?
No creo que esto tenga que ver con campos persistentes. El error se debe a que no es posible la conversión del dato en la bd a un entero. Posiblemente el campo importe no sea un entero o bien es null en cuyo caso tendrías primero que verificar esto antes de hacer la asignación:

// Saludos
Responder Con Cita
  #8  
Antiguo 22-10-2003
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 25
__cadetill Va por buen camino
Algún comentario más (a parte de lo indicado por Román de verificar que no sea null)

A la query le estas pasando una variable. De donde la sacas? no veo que se la asignes!!!

Por qué haces el DisabledControls si no lo tienes ligado a ningún componente visual??

Eso sí, lo más importante es que verifiques que la consulta devuelva algún valor y que no sea nulo antes de hacer asignaciones
Responder Con Cita
  #9  
Antiguo 24-10-2003
Giniromero Giniromero is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid
Posts: 296
Poder: 22
Giniromero Va por buen camino
Hola,


Este es el código con el que consigo que no me de fallos, y me abra la aplicación,

Cita:

PROCEDURE xxxx;
var nAux2: variant;
begin


nAux2:= 0;

Q := TIBQuery.Create(Self);
Q.Database := FrmDmodule.TbEcono.Database;

TRY
Q.Close;
//borramos el contenido de la propiedad SelectSQL
Q.SQL.Clear;
//le asignamos el SQL que tenía al inicio la tabla
Q.SQL.Add('select NUMALU, SUM(0 - econo.impdebe + econo.imphaber) IMPORTE');
Q.SQL.Add('from econo');
Q.SQL.Add('where NUMALU = ' + FrmDModule.TbAlumnosNUMALU.AsString);
Q.SQL.Add('GROUP BY NUMALU ');
Q.SQL.Add('ORDER BY NUMALU ');
Q.Open;
nAux2 := Q.FieldByName('IMPORTE').AsFloat;


lblSaldo1.Caption := formatFloat('#,##0.00 €',nAux2);
FINALLY
FreeAndNil(Q);
END;
lo que pasa, es que, no siempre me muestra, como es de esperar, el saldo real que tiene cada cliente. Creo que, cuando se encuentra campos con valor null, directamente hace mal el calculo, esto es, no considera 0 ese campo null, y no hacer la suma correspondiente. ¿Alguna idea?


Cita:
A la query le estas pasando una variable. De donde la sacas? no veo que se la asignes!!!
eso a sido un despiste del programador ;-)

Cita:
lo más importante es que verifiques que la consulta devuelva algún valor y que no sea nulo antes de hacer asignaciones
y ¿cómo verifico esto?

Gracias por todo, a todos,

Virginia
__________________
Sonrie al mundo, y el mundo te sonreirá :)

Última edición por Giniromero fecha: 24-10-2003 a las 11:23:07.
Responder Con Cita
  #10  
Antiguo 24-10-2003
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 25
__cadetill Va por buen camino
Cita:
Posteado originalmente por Giniromero
y ¿cómo verifico esto?
Yo haría algo así
Código:
if not Q.IsEmpty and not Q.FieldByName('Importe').IsNull then
  // hacer asignación o lo que sea
else
  // Query sin valores o campo nulo
El tema de que te devuelva null la suma, acabo de probar en Firebird 1.5 y, aunque un valor de los que entran en la suma sea Null, la suma en sí la hace correctamente devolciendo la suma de los demás registros
Responder Con Cita
  #11  
Antiguo 24-10-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Cita:
Posteado originalmente por cadetill
El tema de que te devuelva null la suma, acabo de probar en Firebird 1.5 y, aunque un valor de los que entran en la suma sea Null, la suma en sí la hace correctamente devolciendo la suma de los demás registros
Me extraña que la suma te devuelva un valor, en caso de que un registro sea nulo, no deberia hacerlo. Puesto que el estándar SQL indica que un valor operado con nulo, es nulo. Por eso cuando alguno de los valores que interviene en la suma es nulo, el resultado es nulo.

Para solucionarlo, debes utilizar alguna función que te sustituya el nulo por un 0. Por ejemplo, la función COALESCE :

select NUMALU, SUM(0 - COALESCE(econo.impdebe, 0) + COALESCE(econo.imphaber,0)) as IMPORTE
from econo
where NUMALU = :Parametro
GROUP BY NUMALU
ORDER BY NUMALU

El problema es que esto te funcionará en Firebird 1.5, pero creo que Interbase 7 no soporta esta función. En ese caso la tendrás que sustituir por una UDF.

La semana pasada hablamos precisamente de este mismo problema en otro hilo, si lo buscas encontrarás información sobre como utilizar una UDF.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #12  
Antiguo 28-10-2003
Giniromero Giniromero is offline
Miembro
 
Registrado: may 2003
Ubicación: Madrid
Posts: 296
Poder: 22
Giniromero Va por buen camino
Gracias por la ayuda,

Voy a ver si con lo que me has ido facilitando soluciono esto.

Saludos

Virginia
__________________
Sonrie al mundo, y el mundo te sonreirá :)
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 01:42:04.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi