PDA

Ver la Versión Completa : Problemas al Insertar registros de una tabla a otra periódicamente


NEURAL
08-09-2019, 19:15:20
Hola buenas, es mi primera consulta y, como novato, espero me perdonéis si no hago alguna cosa correctamente. Gracias de antemano a todos..

Tengo una duda sobre una consulta SQL ejecutada desde delphi 7 sobre MySQL que me está volviendo loco.. Agradezco si me echáis una mano..

Es simple. Tengo 2 tablas: 'TablaDestino', que está vacía, y 'TablaOrigen' que contiene los valores que deseo insertar en la primera tabla, y deseo hacerlo periódicamente en paquetes de 100 registros ordenados por el ID, es decir, primero copio del 1 al 100, luego del 101 al 200, y así..

Ambas son idénticas en estructura, tienen los mismos campos: ID,DT,TIME,V1,V2. En ambas el ID es la clave primaria autoincremental y el resto son datos sin más. Para ello realizo la siguiente consulta:

'INSERT INTO TablaDestino SELECT * FROM TablaOrigen ORDER BY ID ASC LIMIT 100'

Y luego borro de la tabla 'TablaOrigen' esos 100 registros, de forma que la siguiente vez, coja los 100 siguientes..

Bueno, pues el caso es que lo hace bien la primera consulta (lo he comprobado en ambas tablas, inserta y borra), pero la siguiente vez me da error de sintaxis en la SQL..:confused:

He pensado que podía ser un tema de índices, por lo que he probado a insertar todos los campos menos el indice 'ID', pero tb me da error:

'INSERT INTO TablaDestino (DT,TIME,V1,V2) VALUES (DT,TIME,V1,V2) FROM TablaOrigen ORDER BY ID ASC LIMIT 100'

Alguien me podría dar alguna pista?

Mil gracias

Casimiro Notevi
08-09-2019, 22:13:24
'INSERT INTO TablaDestino (DT,TIME,V1,V2) VALUES (DT,TIME,V1,V2) FROM TablaOrigen ORDER BY ID ASC LIMIT 100'
No recuerdo que se pudiera hacer eso, creo que deben ser todos los campos.

NEURAL
09-09-2019, 11:10:05
Gracias por contestar Casimiro.

Si pongo todos los campos (tb el ID) me sale el mismo error: 'You have an error in your SQL sintax; check de manual.."

He cambiado por esta otra y tampoco..

'INSERT INTO TablaDestino (SELECT ID,DT,TIME,V1,V2 FROM TablaOrigen ORDER BY ID ASC LIMIT 100) ORDER BY ID'

Pero lo desconcertante para mí es que, tanto en ésta última como en la más sencilla y que debería funcionar ('INSERT INTO TablaDestino SELECT * FROM TablaOrigen ORDER BY ID ASC LIMIT 100'), la instrucción la haga bien la primera vez y luego salga el error.. Porque entonces no puede ser un error de sintaxis..

Puede ser que al borrar de la tabla origen los 100 ya copiados pase algo con los índices que a mí se me escapa? En las tablas no veo ningún indice duplicado ni saltado.. Aparentemente lo hace bien cada vez que lo pongo en marcha (solo que solo lo hace una vez y a la siguiente sale el error).

Alguna sugerencia?

Muchas gracias!

Casimiro Notevi
09-09-2019, 11:11:23
Habría que ver el código que usas, poco más podemos ayudar con esa información.

NEURAL
09-09-2019, 12:56:23
Habría que ver el código que usas, poco más podemos ayudar con esa información.

Ahí va el código:

procedure TFprincipal.THaonlineTimer(Sender: TObject);
VAR
idprimero:integer;
begin
Consulta.Close;
Consulta.SQL.Add('INSERT INTO '+Tabladestino.TableName+' SELECT * FROM '+TablaOrigen.TableName+' ORDER BY ID ASC LIMIT 100');
Consulta.ExecSQL;
Tabladestino.ApplyUpdates;

TablaOrigen.Open;
TablaOrigen.first;
idprimero:=TablaOrigen.Fieldbyname('ID').asinteger;
Consulta.Close;
Consulta.SQL.Clear;
Consulta.SQL.Add('DELETE FROM '+TablaOrigen.TableName);
Consulta.SQL.Add(' WHERE ID>=:miID1 AND ID<=:miID2');
Consulta.ParamByName('miID1').asinteger:= idprimero;
Consulta.ParamByName('miID2').asinteger:= idprimero+99;
Consulta.ExecSQL;
TablaOrigen.ApplyUpdates;
TablaOrigen.close;
end;

Las Tablas tienen la propiedad cachedupdates a true. El procedimiento es un evento Ontimer que se ejecuta cada 5 sg.

Si necesitáis información distinta a ésta me decís..

Gracias

bucanero
09-09-2019, 14:00:26
hola a todos!!

Prueba añadiendo un SQL.clear antes de hacer la consulta INSERT INTO (linea en rojo del código)

procedure TFprincipal.THaonlineTimer(Sender: TObject);
var
idprimero: integer;
begin
Consulta.Close;
Consulta.SQL.clear;
Consulta.SQL.Add('INSERT INTO ' + Tabladestino.TableName + ' SELECT * FROM ' + TablaOrigen.TableName + ' ORDER BY ID ASC LIMIT 100');
Consulta.ExecSQL;
Tabladestino.ApplyUpdates;

TablaOrigen.Open;
TablaOrigen.first;
idprimero := TablaOrigen.Fieldbyname('ID').asinteger;
Consulta.Close;
Consulta.SQL.Clear;
Consulta.SQL.Add('DELETE FROM ' + TablaOrigen.TableName);
Consulta.SQL.Add(' WHERE ID>=:miID1 AND ID<=:miID2');
Consulta.ParamByName('miID1').asinteger := idprimero;
Consulta.ParamByName('miID2').asinteger := idprimero + 99;
Consulta.ExecSQL;
TablaOrigen.ApplyUpdates;
TablaOrigen.close;
end;

Casimiro Notevi
09-09-2019, 14:00:43
No olvides usar las etiquetas para el código.


https://www.clubdelphi.com/images/UtilizarTAGs.png

Casimiro Notevi
09-09-2019, 14:03:14
Prueba añadiendo un SQL.clear antes de hacer la consulta INSERT INTO (linea en rojo del código)
Ese es el problema.
Siempre utilizo sql.text en lugar de add, porque así no hay problema nunca.

consulta.sql.text := 'select ...';

NEURAL
09-09-2019, 16:24:44
hola a todos!!

Prueba añadiendo un SQL.clear antes de hacer la consulta INSERT INTO (linea en rojo del código)

procedure TFprincipal.THaonlineTimer(Sender: TObject);
var
idprimero: integer;
begin
Consulta.Close;
Consulta.SQL.clear;
Consulta.SQL.Add('INSERT INTO ' + Tabladestino.TableName + ' SELECT * FROM ' + TablaOrigen.TableName + ' ORDER BY ID ASC LIMIT 100');
Consulta.ExecSQL;
Tabladestino.ApplyUpdates;

TablaOrigen.Open;
TablaOrigen.first;
idprimero := TablaOrigen.Fieldbyname('ID').asinteger;
Consulta.Close;
Consulta.SQL.Clear;
Consulta.SQL.Add('DELETE FROM ' + TablaOrigen.TableName);
Consulta.SQL.Add(' WHERE ID>=:miID1 AND ID<=:miID2');
Consulta.ParamByName('miID1').asinteger := idprimero;
Consulta.ParamByName('miID2').asinteger := idprimero + 99;
Consulta.ExecSQL;
TablaOrigen.ApplyUpdates;
TablaOrigen.close;
end;


Mil gracias Bucanero!! Vaya fallo tonto :o Está claro que el ojo no ve lo evidente a veces.. Podía haber estado semanas sin darme cuenta!!!

Gracias de nuevo:)

NEURAL
09-09-2019, 16:27:54
Ese es el problema.
Siempre utilizo sql.text en lugar de add, porque así no hay problema nunca.

consulta.sql.text := 'select ...';



Gracias, tienes razón.. Con text esto no me hubiera pasado.. Y no volverá a pasar..

Ah y utilizaré las etiquetas!

Un saludo y gracias de nuevo