Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Consulta con hora en access (https://www.clubdelphi.com/foros/showthread.php?t=68867)

ElDioni 12-07-2010 13:25:31

Consulta con hora en access
 
Buenos días a todos,
he estado buscando por los foros pero no he encontrado algo que me solucione el problema, os cuento, he puesto una consulta de sql

Código Delphi [-]
Adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario=' + quotedstr(adoquery2.FieldByName('Usuario').AsString) + ' AND leido=false AND (fechaprog<=#'+datetostr(date)+'# AND horaprog<=#'+timetostr(time)+'#)';

Esto me dice que "el objeto parameter está mal definido bla,bla bla", sucede porque la hora lleva en su cadena los dos puntos (:) y lo considera un parametro, entonces voy y pongo la hora como parametro y se lo paso desde fuera, me queda así.

Código Delphi [-]
adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario=' + quotedstr(adoquery2.FieldByName('Usuario').AsString) + ' AND leido=false AND (fechaprog<=#'+datetostr(date)+'# AND horaprog<=#:hora#)';
adoquery1.Parameters.ParamByName('Hora').Value:=time;

Pero entonces me dice que le parametro hora no existe y supongo que es porque considera que el parametro se llama :hora#, me coge la almohadilla como nombre del parametro, pero en access tengo que pasarle las fechas y las horas con almohadillas.

¿Que otra cosa puede probar?, ¿se os ocurre algo?, gracias de antemano y espero que se me haya entendido.

Un saludo.

Caral 12-07-2010 15:17:08

Hola
Código Delphi [-]
adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario=' + quotedstr(adoquery2.FieldByName('Usuario').AsString) +
' AND leido = false AND fechaprog <= #'+datetostr(date)+
'# AND horaprog<= :hora';
adoquery1.Parameters.ParamByName('Hora').Value:=time;
Saludos

ElDioni 12-07-2010 16:42:05

Gracias por responder tan rápido Caral, pero el problema es que si en la hora no le meto las almohadillas, como en la fecha, access no me toma bien la consulta.

En la solución que me pones le quitas las almohadillas que te comento:
Código Delphi [-]
adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario=' + quotedstr(adoquery2.FieldByName('Usuario').AsString) +
' AND leido = false AND fechaprog <= #'+datetostr(date)+
'# AND horaprog<= :hora';
adoquery1.Parameters.ParamByName('Hora').Value:=time;
Pero yo debería dejarlo así:
Código Delphi [-]
adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario=' + quotedstr(adoquery2.FieldByName('Usuario').AsString) +
' AND leido = false AND fechaprog <= #'+datetostr(date)+
'# AND horaprog<=#:hora#';
adoquery1.Parameters.ParamByName('Hora').Value:=time;

Y de esta forma, como te comentaba un poco más arriba, me dice que el parametro hora not found (supongo yo que es porque toma el parametro como si fuera :hora#)
Gracias de todas formas por tu ayuda, a ver si se te ocurre algo porque estoy bantante perdido.
Un saludo.

Faust 12-07-2010 17:02:26

Ya me había ocurrido antes y creo que si:

Código Delphi [-]
... + '# AND horaprog<=#:hora#';

Así es, si :hora es un parámetro, lo estás poniendo dentro de un string, lo digo por las comillas.

Porqué no lo haces de esta forma como lo hiciste en el campo anterior???

Código Delphi [-]
... AND fechaprog <= #'+datetostr(date)+

Creo que de alguna manera están interviniendo negativamente las almohadillas en combinación con los dos puntos de tu parámetro, quizás te funcione mejor así.

Código Delphi [-]
... + '# AND horaprog<=#' + DateToStr(TimeHoraProg) + '#';

Saludos

ElDioni 12-07-2010 17:12:54

Hola Faust, gracias a ti también por responder tan rápido,
el caso es que como lo tenía al principio, que era con TimeToStr(time), me suelta el error de "objeto parameter mal definido" y creo que es porque al ser una hora me considera a partir de los dos puntos el parametro (12:16) el parametro sería :16 (o por lo menos creo yo que pasa esto). Si pongo, como me comentas, datetostr(time) me pone, en lugar de una hora, la fecha del 31/12/1899, por lo que tampoco puedo solucionarlo de esta forma, sigo probando cosas, ¿no se podría hacer un cast al valor de SQL y al de delphi para que en vez de una hora comparara un número?, no se, como os digo sigo probando.
Un saludo.

Caral 12-07-2010 17:41:39

Hola
Código Delphi [-]
var
Hora1: TTime;
begin
Hora1: Now;
ShortDateFormat := '#yyyy/mm/dd#';
adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario=' + quotedstr(adoquery2.FieldByName('Usuario').AsString) +
' AND leido = false AND fechaprog <= '+datetostr(date)+
' AND horaprog<= :hora';
adoquery1.Parameters.ParamByName('Hora').Value:= FormatDateTime('hh:mm:ss',Hora1);
End;
Saludos

ElDioni 12-07-2010 18:14:29

Hola Caral, lo que ocurre es que con la fecha no tengo ningún problema, si quito la parte de "horaprog" la consulta funciona correctamente, ahora, al añadir "horaprog", que es un campo que está guardado en access en formato fecha/hora del tipo de hora larga, si no le pongo las almohadillas no me da ningún error, pero tampoco me devuelve ningún registro y tengo registros que cumplen la condición, y al ponerle las almohadillas me da el error que antes te comentaba, si pongo directamente la consulta, con sus almohadillas correspondientes, en access la consulta funciona correctamente y me saca los registros que tiene que sacar, el valor que le tengo que pasar para hacer la comparación a "HoraProg" tiene que quedar así: #12:10#, por ejemplo.
¿No se si se me explico bien?.
Un saludo.

Caral 12-07-2010 18:25:57

Hola
Código Delphi [-]
var
Hora1: TTime;
begin
Hora1: Now;
ShortDateFormat := '#yyyy/mm/dd#';
ShortTimeFormat := '#hh:mm:ss#';
adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario=' + quotedstr(adoquery2.FieldByName('Usuario').AsString) +
' AND leido = false AND fechaprog <= '+datetostr(date)+
' AND horaprog<= :hora';
adoquery1.Parameters.ParamByName('Hora').Value:= Hora1;
End;
No se, cualquier cosa nos pasas el programa y la bd y lo revisamos a ver cual es el error.
Saludos

Faust 12-07-2010 18:37:04

Cita:

Empezado por ElDioni (Mensaje 370072)
...Si pongo, como me comentas, datetostr(time) me pone, en lugar de una hora, la fecha del 31/12/1899...

Ay perdón, ahora si la cagu*... ja ja ja :D tienes razón es TimeToStr... yo recuerdo que hace unos tres años solucioné esto... pero no me acuerdo como deja pienso un poco.

Faust 12-07-2010 18:42:19

Creo que ya sé...

A ver...

Construye toda tu consulta sin parámetros y en el query pones la propiedad ParamCheck a False y ahora si le pones como te recomendé en mi primer respuesta

Código Delphi [-]
... + '# AND horaprog<=#' + TimeToStr(TimeHoraProg) + '#';

Ahora si con TimeToStr o más bien, como en tu pregunta con la que abres el hilo

Código Delphi [-]
Adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario=' + 
                    quotedstr(adoquery2.FieldByName('Usuario').AsString) + 
                    ' AND leido=false AND (fechaprog<=#'+datetostr(date) + 
                    '# AND horaprog<=#'+timetostr(time)+'#)';

Creo que así lo resolví... :cool:

Lo que pasa es que tienes razón, los dos puntos de la hora los confunde con parámetros y se hace bolas, al poner ParamCheck a False queda inhabilitado el uso de parámetros, pero si construyes tu Select como en esta última opción no tendrás problemas.

ElDioni 12-07-2010 18:46:09

Os paso el trozo de código de la discordia y la tabla a la que le hago la consulta.

Código Delphi [-]
adoquery4.Close; 
adoquery4.SQL.Text:='SELECT * FROM log WHERE destinatario=' + quotedstr('Dioni') + ' AND leido=false AND (fechaprog <=#' + datetostr(date) + '# AND horaprog<=#' + timetostr(time) + '#)'; 
adoquery4.ExecSQL; 
adoquery4.Open; 
if adoquery4.IsEmpty then   
  begin     
    showmessage('Vacio');   
  end 
else   
  begin     
    showmessage(adoquery4.FieldByName('mensaje').AsString);   
end;

Un saludo

ElDioni 12-07-2010 19:02:15

Señores me tengo que marchar, hasta mañana no me pondré de nuevo con este tema, lo digo por que no podré responderles si escriben alguna solución, no quiero que crean que nos le hago caso. Mañana les contaré si se me ocurrió algo.
Un saludo y gracias.

Caral 12-07-2010 19:21:15

Hola
Asi me funciona perfectamente:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShortDateFormat := '#dd/mm/yyyy#';
  ShortTimeFormat := '#hh:mm:ss#';
  adoquery1.Close;
  adoquery1.SQL.Text:='SELECT * FROM log WHERE destinatario =' +Quotedstr('Dioni') +
  ' AND leido = false AND fechaprog <= :dia'+
  ' AND horaprog <= :hora';
  adoquery1.Parameters[0].Value:= Date;
  adoquery1.Parameters[1].Value:= Time;
  adoquery1.Open;
  if adoquery1.IsEmpty then
  begin showmessage('Vacio');
  end
  else begin showmessage(adoquery1.FieldByName('mensaje').AsString); end
end;
Saludos

ElDioni 13-07-2010 09:33:40

Como os comentaba ayer he vuelto con el asunto esta mañana, muchas gracias a los dos por vuestro tiempo y vuestras propuestas, al final con la opción de Faust me funciona perfecto, al final se queda así:

Código Delphi [-]
adoquery4.ParamCheck:=false;
adoquery4.Close;
adoquery4.SQL.Text:='SELECT * FROM log WHERE (destinatario=' + 
quotedstr(adoquery2.FieldByName('Usuario').AsString) +
' AND leido=false) AND ((fechaprog<#'+datetostr(date)+'#)OR(fechaprog=#'+
datetostr(date)+'# AND horaprog<=#'+timetostr(time)+'#))';
adoquery4.ExecSQL;
adoquery4.Open;

He tenido que modificar la consulta porque ayer a las 13:00 si me sacaba los mensajes que tenían la fecha de ayer y las 12:00 en la hora, pero hoy a las 8:00 de la mañana, de la forma en que lo tenía puesto, no me sacaba los mensajes, aparte de eso todo genial.
He probado también tu opción Caral y me sigue apareciendo el mensaje de vacío, no se si tendrá que ver con la versión de access que yo tengo que es la :eek: 97 :eek:, de todas formas gracias de nuevo a los dos.
Un saludo.

Faust 13-07-2010 17:10:09

Cita:

Empezado por ElDioni (Mensaje 370165)
Como os comentaba ayer he vuelto con el asunto esta mañana, muchas gracias a los dos por vuestro tiempo y vuestras propuestas, al final con la opción de Faust me funciona perfecto, al final se queda así:

Código Delphi [-]adoquery4.ParamCheck:=false; adoquery4.Close; adoquery4.SQL.Text:='SELECT * FROM log WHERE (destinatario=' + quotedstr(adoquery2.FieldByName('Usuario').AsString) + ' AND leido=false) AND ((fechaprog<#'+datetostr(date)+'#)OR(fechaprog=#'+ datetostr(date)+'# AND horaprog<=#'+timetostr(time)+'#))'; adoquery4.ExecSQL; adoquery4.Open;


He tenido que modificar la consulta porque ayer a las 13:00 si me sacaba los mensajes que tenían la fecha de ayer y las 12:00 en la hora, pero hoy a las 8:00 de la mañana, de la forma en que lo tenía puesto, no me sacaba los mensajes, aparte de eso todo genial.
He probado también tu opción Caral y me sigue apareciendo el mensaje de vacío, no se si tendrá que ver con la versión de access que yo tengo que es la :eek: 97 :eek:, de todas formas gracias de nuevo a los dos.
Un saludo.

Veo que al final de tu código pones:

Código Delphi [-]
adoquery4.ExecSQL;
adoquery4.Open;
No debería de ser, el funcionamiento de cada una es el siguiente:

ExecSQL se utiliza cuando tu SQL no regresa datos, p. ej. cuando es una inserción, modificación, etc.

Open se utiliza cuando tu consulta retorna un conjunto de datos, p. ej. un SELECT, la ejecución de un procedimiento almacenado que devuelva registros, etc.

Saludos... y toma en cuenta esto último.

ElDioni 14-07-2010 12:59:25

Gracias Faust, lo tendré en cuenta.

Un saludo.


La franja horaria es GMT +2. Ahora son las 03:51:09.

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