Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Consulta TADOQuery con Fechas (https://www.clubdelphi.com/foros/showthread.php?t=10593)

Leonard 24-05-2004 04:02:52

Consulta TADOQuery con Fechas
 
Hola Amigos..!! :(


Ante todo muchas Gracias, quisiera que me ayudaran con el siguiente problema:


Poseo las Tablas: T_Proveedor
T_Factura_Compra

y un TADOQuery: Q_Factura_Compra que posee los siguientes campos:


Cod_Factura
Cod_Proveedor
Fech_Factura
Sub_Total



En un Formulario poseo 2 Tcombobox que sirven de parametros:

CB_Año : Para Seleccionar un determinado año.
CB_Mes : pasar seleccionar un mes Correspondiente.


y ademas poseo una dbgrid la cual esta enlazada a Q_Factura_Compra


Quisiera realizar una consulta personalizada de todas las Facturas de compra de un mes y un Año determinado,
segun los parametros seleccionados por el usuario a travez de los TCombobox antes mencionados.

Lo estoy haciendo del siguiente modo pero no se como manejar los filtros por mes y año


With Mdatos.Q_Factura_Compra Do
Begin
Close;
parameters.AddParameter.Name := 'mes';
parameters.AddParameter.Name := 'ano';
Parameters.ParamByName('mes').DataType := ftDateTime;
Parameters.ParamByName('ano').DataType := ftDateTime;
Parameters.ParamByName('mes').Value := CB_Mes.Text;
Parameters.ParamByName('ano').Value := CB_ano.Text;
With Sql Do
Begin
Clear;
Add('Select * from T_Fact_Compra ');
Add('Where ((Fech_Factura= :mes)and(Fech_Factura= :ano)) ');
End;
prepared;
Open;
End;


Sucede que dice que el parametro es invalido, he tratado de usar la Funcion strtodatetime pero sucede lo mismo..



Se les Agracede la ayuda que me puedan prestar...!!

jachguate 24-05-2004 04:18:16

Hola.

Lamentablemente no has indicado el motor de base de datos con el que trabajas. Los parámetros debiera "encontrarlos" ADO al asignar la sentencia SQL, por lo que no veo razón para hacer un AddParameter. Por otro lado, el mes y el año, no debieran ser un dateTime sino un Integer o SmallInt... no te parece??

Luego, tu motor debiera proveer alguna forma de obtener el mes y el año de una fecha. En firebird es la función extract, que se usa asi:

Código SQL [-]
Select *
 from t_fact_compra
 where extract(month from fech_factura) = :mes
   and extract(year from fech_factura) = :anio;

En cambio en Oracle podes valerte de las funciones to_number y to_char, asi:

Código SQL [-]
Select *
 from t_fact_compra
 where to_number(to_char(fech_factura, 'MM')) = :mes
   and to_number(to_char(fech_factura, 'YYYY')) = :anio;

Luego, he visto en menos de dos días a dos personas que primero asignan el valor de los parámetros y luego la sentencia SQL. Aunque ado podria soportarlo, segun la ayuda de la propiedad ParamCheck, me parece poco lógico hacerlo de esa forma.

Desde mi punto de vista es mas "sano" y "normal" asignar primero la sentencia SQL, de donde el motor extraerá los nombres de los parámetros, y luego asignar los valores a estos.

Hasta luego.

;)

delphi.com.ar 24-05-2004 04:21:50

En Delphi y en muchos motores de bases de datos, los campos o variables del tipo fecha hora, no dejan de ser números decimales del cual la parte entera forma la fecha y la decimal la hora. Digamos que no sería algo muy correcto comparar 'CAMPO_FECHA = 01', donde solo nosotros sabemos que con 01 queremos decir mes. Muchos motores tienen funciones de conversión de datos que nos pueden ser útil para esto, como el TO_DATE de Oracle, o bien funciones para extraer el mes y la fecha, utilizando estas últimas tu sql podría funcionar de la siguiente manera:
Código SQL [-]
SELECT * 
FROM TABLA
WHERE Month(FECHA_FACTURA) = :Mes
AND Year(FECHA_FACTURA) = :Ano

Saludos!

Leonard 24-05-2004 05:07:54

Continua el Problema TADOQuery con Fechas
 
Hola Amigos Agradesco su respuesta es casi inmediata, Pero continuo con el problema aun...!!.

Aqui les doy algunos datos mas a ver que me pueden ayudar; Poseo un Modulo de datos en el cual utilizo TADOConnection para enlazar las TADOTable con la base de datos elaborada en Access; Utilizo el Driver Microsoft Jet 4.0 OLE DB PROVIDER.

Importante: A Travez de los Tcombosbox los usuarios seleccion la fecha y año respectivamente que sera enviadas como parametros al query

With Mdatos.Q_Fact_Compra Do
Begin
Close;
parameters.AddParameter.Name := 'mes';
parameters.AddParameter.Name := 'ano';
Parameters.ParamByName('mes').DataType := ftSmallInt;
Parameters.ParamByName('ano').DataType := ftSmallInt;
Parameters.ParamByName('mes').Value := strtoint(CB_mes.Text);
Parameters.ParamByName('ano').Value := strtoint(CB_ano.Text);
With Sql Do
Begin
Clear;
Add('Select * from T_Factura_Compra ');');
Add('Where (month(Fech_Factura)= :mes) and (year Fech_Factura)= :ano');
End;
prepared;
Open;
End;



Tambien utilize el codigo recomendado

WHERE Month(FECHA_FACTURA) = :Mes AND Year(FECHA_FACTURA) = :Ano



Intente las recomendaciones pero los mensajes de Error son los Siguientes:
1.- No se han espeficado valores para algunos parametros requeridos
2.- error no especificado..!!

Probe la ejecucion sin la instruccion where y Funciona perfectamente. Supongo que es un Error de asignacion de Tipos.


Agradesco lo que me puedan ayudar, llevo varios dias intentando resolver este problema...!!

jachguate 24-05-2004 05:54:20

Cita:

Empezado por jachguate
he visto en menos de dos días a dos personas que primero asignan el valor de los parámetros y luego la sentencia SQL. Aunque ado podria soportarlo, segun la ayuda de la propiedad ParamCheck, me parece poco lógico hacerlo de esa forma.

Desde mi punto de vista es mas "sano" y "normal" asignar primero la sentencia SQL, de donde el motor extraerá los nombres de los parámetros, y luego asignar los valores a estos.

Leiste esto?

fjcg02 25-05-2004 13:36:57

Yo dispararía con posta...

Quiero decir, que puedes 'traducir' la query a valores entre fechas, y pasar de meses y años.

Código:

//Año=2000 ->
SQL.Add('Select * from tabla');
SQL.Add('where fecha_factura >= '+ quotedstr(01/01/2000)+' and fecha_factura<= ' +Quotedstr(31/12/2000);

//Año = 2000 y Mes=02
SQL.Add('Select * from tabla');
SQL.Add('where fecha_factura >= '+ quotedstr(01/02/2000)+' and fecha_factura<= ' +Quotedstr(29/02/2000)

Ten en cuenta que tendrás que 'manipular' mínimamente la generación de fechas para ajustarlo, pero esto funciona perfectamente.

Otra solución es pasar de años meses y pirulas , y que se introduzcan los límites en formato fecha. Desde fecha hasta fecha. Que quieres un año entero, desde el 1 de Enero al 31 de Diciembre. Que quieres un mes, desde el 1 del mes al último día del mes. Que el usuario haga algo demonios, que no se limite a quejarse únicamente.

Por cierto, si cada vez generas el código de la query ¿ para qué utilizas parámetros ? Lo lógico es que dejes la query parametrizada y sólo cambies el valor de los susodichos interfectos, es decir, los parámetros.

Espero no haberte liado mucho y que te sirva de ayuda

Un saludo

jachguate 25-05-2004 17:21:13

Hola.

Lo propuesto por fjcg02 también es válido, pero acotaría dos cosas.
  • Si vas a comparar por un rango de fechas, es mejor que uses el operador between y no el mayor que y menor que para indicar el rango. Algunos motores optimizarán mejor el query al seguir esta recomendación.
  • Seguí usando parámetros. Eso te dará mucha independencia del motor de base de datos y su configuración, pues hay motores que reconocerán la cadena de fecha siempre que esté en el formato que reconozcan o para el que esten configurado, y esto puede ocasionarte problemas. Al utilizar parámetros, delegas la responsabilidad a ADO la responsabilidad de "acordar" el formato de fecha con el cliente de la BD. Además, en ciertos motores (como oracle) aprovechas las prestaciones de cache de sentencias, ahorrando tiempo al no tener que reanalizarla cuando la ejecutas de nuevo
  • Al asignar la sentencia SQL en tiempo de ejecución, asumo que es una sentencia genérica que usas para diferentes consultas. Si no es asi, como ya dijo fjcg02, basta con que asignes valor a los parámetros.

Hasta luego.

;)

carlosmoralesm 25-06-2004 22:46:09

Hola a todos

yo he usado este codigo en el query

SELECT *
FROM Log
WHERE Fecha BETWEEN :Fechai AND :Fechaf

y en delphi

qrylog.Parameters.ParamByName('fechai').Value:=datetostr(fechailog.Date)+' '+horailog.Text;
qrylog.Parameters.ParamByName('fechaf').Value:=datetostr(fechaflog.Date)+' '+horaflog.Text;

y me ha funcionado muy bien espero te sirva de algo
probado con delphi 7 y msacces

las fechas vienen de un Datapicker y la hora de un edit
los parametros estan como Datetime

y funciona muy bien


La franja horaria es GMT +2. Ahora son las 02:49:23.

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