PDA

Ver la Versión Completa : Problema con una consulta hecha de 3 formas


VRO
21-01-2005, 19:12:06
Hola, tengo un problemón llevo 8 horas para hacer una consulta, la he intentado hacer de 3 formas distintas.

Primeramente utilizo la tabla texportar (contador,fecha,lectura,consumo) son sus campos.
Lo que pretendo es exportar datos a esta tabla mediante un query y lo que tiene que hacer la consulta es si el contador (que es la clave principal de la tabla) que pretendo introducir en la tabla texportar ya existe en esa tabla modifico sus datos (fecha,lectura,consumo) y si no existe los inserto. Necesito hacer la consulta de una vez para evitar la conexión repetida al servidor ya que la consulta está dentro de un bucle ó lazo.

Acontinuación os pongo el código de como la intentado hacer.Por cierto utilizo Firebird 1.5:

La primera opción por la que opté fue:

query.Close;
query.SQL.Add('replace texportar(contador,fecha,lectura,consumo)VALUES ('+datos.IBADOQ.fieldbyname('numero').text+',#'+FormatDateTime('mm/dd/yy',datos.IBADOQ.fieldbyname('fecha').asdatetime)+'#,'+datos.IBADOQ.fieldbyname('lectura').text+','+ datos.IBADOQ.fieldbyname('consumo').text+')');
query.ExecSQL;


Creo que no ha resultado porque el replace pertenece a MySql y no a SQL estandar,si no me equivoco.

Segunda forma:

query.SQL.Clear;
query.SQL.Add('insert into texportar(contador,fecha,lectura,consumo)values('+ datos.IBADOQ.fieldbyname('numero').text+',#'+FormatDateTime('mm/dd/yy',datos.IBADOQ.fieldbyname('fecha').asdatetime)+'#,'+datos.IBADOQ.fieldbyname('lectura').text+','+ datos.IBADOQ.fieldbyname('consumo').text+')on duplicate key (update fecha=#'+FormatDateTime('mm/dd/yy',datos.IBADOQ.fieldbyname('fecha').asdatetime)+'#, lectura='+datos.IBADOQ.fieldbyname('lectura').text+ ',consumo='+datos.IBADOQ.fieldbyname('consumo').text+')');
query.ExecSQL;


Esta opción creo que falla por lo mismo que la anterior porque el on duplicate key es de MySql

Tercera:

query.Close;
query.SQL.Text:='INSERT INTO texportar SELECT contador,fecha,lectura,consumo, (IF ((SELECT contador FROM texportar';
query.SQL.Text:=query.sql.Text+' WHERE contador<>'+datos.IBADOQ.fieldbyname('numero').text+')then';
query.SQL.Text:=query.sql.Text+' INSERT INTO texportar (contador,fecha,lectura,consumo)values('+datos.IBADOQ.fieldbyname('numero').text+'';
query.SQL.Text:=query.sql.Text+',#'+FormatDateTime('mm/dd/yy',datos.IBADOQ.fieldbyname('fecha').asdatetime)+'#,'+datos.IBADOQ.fieldbyname('lectura').text+'';
query.SQL.Text:=query.sql.Text+','+datos.IBADOQ.fieldbyname('consumo').text+')else UPDATE texportar'+'';
query.SQL.Text:=query.sql.Text+'SET fecha=#'+FormatDateTime('mm/dd/yy',datos.IBADOQ.fieldbyname('fecha').asdatetime)+'#'; query.SQL.Text:=query.sql.Text+',lectura='+datos.iBADOQ.fieldbyname('lectura').Text+',consumo='+dato s.IBADOQ.fieldbyname('consumo').Text+' where contador='+ datos.IBADOQ.fieldbyname('numero').Text+')) from texportar';
query.Open;


Esta opción realmente no se porque falla ya que los if si son permitidos en Sql estandar.

Por favor, si laguien sabe como resolver esta consulta, ó si sabe otra forma de hacerla aunque sea partiendo la consulta en varias..

P.D:
datos.IBADOQ= corresponde a otro query de interbase ya que con el saco los datos que quiero exportar.

desde ya mismo , muchas gracias.

roman
21-01-2005, 19:22:22
Tu mensaje es casi imposible de leer.

Te sugiero que lo edites para cortar las líneas. Más aún, sería mejor si escribieras las consultas SQL directamente sin código Delphi.

// Saludos

Héctor Randolph
21-01-2005, 20:05:51
Hola VRO!

Con respecto a esta consulta coincido en que es mejor hacerla directamente en SQL.

Ya que estás utilizando FireBird 1.5 puedes aprovechar la sintaxis de los
procedimientos almacenados para facilitarte este trabajo.

En la definición del procedimiento puedes declarar las variables y los parámetros,
utilizar sentencias IF THEN ELSE, WHILE , etc.

Un ejemplo:


SET TERM!!;
CREATE PROCEDURE PRUEBA( param1 INTEGER, param2 VARCHAR(40))
AS
DECLARE VARIABLE var1 INTEGER;
BEGIN
SELECT
COUNT(clave)
FROM tabla1
WHERE clave=:param1;
INTO :var1;/*Cuenta los registros y los almacena en var1*/

IF (var1=0) THEN
INSERT INTO tabla1 (clave,nombre)
VALUES (:param1,:param2);
ELSE
UPDATE tabla1
SET nombre=:param2
WHERE clave=:param1;
.
.
.
END!!
SET TERM;!!


Te recomiendo que busques información de los procedimientos almacenados en Firebird.

Un Saludo.

VRO
24-01-2005, 08:45:53
Perdonad pero se ma ha olvidado deciros lo mas importante, la tabla texportar no es una tabla de la base de datos Firebird 1.5 si no que es una tabla que he creado yo directamente con codigo Delphi, en Access, solamente para exportar los datos de la tabla lecturas de Firebird 1.5(numero,fecha,lecturas, consumo), por lo que la comprobación de si existe el contador modifico los datos y si no existe inserto el datos es sobre una tabla en Access poerlo que no pùedo utilizar procedimientos almacenado ya que Access no tiene esa función.

Espero que después de esta torpeza siga contando con vuestra ayuda. Muchas gracias

VRO
24-01-2005, 18:20:02
Gracias, en verdad al final lo he hecho con procedimientos almacenado guardandolo en una tabla en Interbase y despues transportanto los registros a Access

Héctor Randolph
24-01-2005, 19:02:11
Espero que después de esta torpeza siga contando con vuestra ayuda.

Estoy seguro de que en este foro siempre encontrarás algún amigo que este dispuesto a brindar ayuda, eso ni duda cabe. :)

Por otra parte yo no le llamaría torpeza, todos aquí estamos en el mismo proceso de aprendizaje y retroalimentación.

Un saludo. ;)