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)
-   -   Migración BD Paradox a Mysql en RED (https://www.clubdelphi.com/foros/showthread.php?t=91348)

koalasoft 09-01-2017 23:24:13

Migración BD Paradox a Mysql en RED
 
Estimados necesito su orientación ...

Ya de hace alguno tiempo vengo programando con Delphi 7 y usando el motor de BD Paradox para sistemas Locales, tengo un sistema ya terminado, pero ahora requiero que en lugar de ser una BD Local, sea de compartido y por Red, al decir compartido es para que varios usuarios puedan usar las tablas al mismo tiempo ya sea para consulta o trabajar en ellas, por cuestiones de tiempo no puedo "por ahora" usar otro tipo de sistema, osea veo en los foros que recomiendan usar firebird entre otros ..

Pero en mi caso ya que el sistema esta corriendo bien local migrarlo a una base de datos compartida, por que a Mysql, bueno considero que este manejador es muy confiable "cuestión de gustos", estuve usando los componentes Table y Datasource para tal trabajo (guardar, modificar, eliminar) y para las consultas usaba el query con sentencias SQL. Veo que hay un poco de similitud usando las tablas ADOTable, mi pregunta sería .. es suficiente usar en lugar de usar las TTables ahora el ADOTable para guardar mi datos?..

Para guardar usaba la sintaxis:

Código PHP:

Table1.insert;
try
Table1.FieldByName('CONT').AsInteger:=StrToInt(Edit1.Text);
Table1.FieldByName('NOM').AsString:=Edit2.Text;
finally
Table1
.post;
end

Para Editar el:

Código PHP:

Table1.Edit;
try
Table1.FieldByName('CONT').AsInteger:=StrToInt(Edit1.Text);
Table1.FieldByName('NOM').AsString:=Edit2.Text;
finally
Table1
.post;
end

y para eliminar el :

Código PHP:

Table1.Delete

Puedo seguir usando los mismo parámetros ahora con el ADOTable? o es que se requiere hacer as cosas ..

Escenario:

La Base de datos estará en Mysql en un equipo en red llámese "equiposerver"
Otro equipo estará en la misma red para hacer las operaciones llámese "equipoperador"
y un último equipo solo para consulta, llámese "equipocosulta"


Lo que se requiere es que el "equipoperador" al momento que este trabajando (cargando,editando, borrando datos) pueda el "equipoconsulta" poder hacer "valga la redundancia" realizar consultas y generar reportes, estos dos trabajando simultaneamente en el "equiposervidor".

Me podrían aclarar si es correcto que lo que expongo o hay alguna mejor idea?

Gracias por su tiempo!!

koalasoft 10-01-2017 05:02:23

Bueno, hasta ahora he logrado convertir mis BD Paradox a Mysql con una herramienta, todo bien hasta ahora...

Estuve practicando con un formulario nuevo para visualizar los datos de la Tabla (ahora en sql) en un DBGrid, agregé un AdoConnection + DataSoucer + AdoQuery


Logre hacer una buena conección a la Base de datos conectando el DataSoucer al ADOQuery y el ADOQuery al ADOConecction. Lo active y listo .. se visualizó mis datos en en DBGrid, incluso agregué un DBText vinculando con un ADOTable para que igual alli me mostrara los datos ...


Practiqué la búsqueda con e ADOQuery ta cual lo hacia con el Query y veo funcionó muy bien .. eso si, es ligeramente tardado la búsqueda pero la realiza finalmente.

Ahora lo que intenté es hacer la opción de Editar un campo .. usé el ADOTable con el siguiente código ..

Antes con el Table buscaba el campo llave para posicionarme en el registro y así poder realizar el cambio .. lo hacía con
Table1.FindKey([algo]), por ejemplo

Código PHP:

if Table1.FindKey([Edit1.Txt]) Then
  showmessage 
('Encontrado'

Ahora con el ADOTable veo no me aparece tal parámetro, intenté hacerlo usando FindField, pero veo no funcionó, al menos no como esperaba.
Código PHP:

if ADOTable1.Active True Then
   ADOTable1
.Active:= False;

ADOTable1.Active := True;

if 
ADOTable1.FindField('ID_CL').AsInteger  StrToInt(DBText1.CaptionThen
  Begin
  showmessage
('Encontrado');
  
End
   
Else
    
Begin
     showmessage
('No Encontrado');
    
End

La comparación lo hice con el DBText ya que alli aparece el ID llave para buscar el registro, pero si hago otra búsqueda y el DBText cambia este no lo encuentra ...

Alguna idea o voy mal ??

Neftali [Germán.Estévez] 10-01-2017 09:53:33

Cita:

Empezado por koalasoft (Mensaje 512257)
Puedo seguir usando los mismo parámetros ahora con el ADOTable? o es que se requiere hacer as cosas ..

...

Me podrían aclarar si es correcto que lo que expongo o hay alguna mejor idea?

En principio, puedes seguir utilizando el mismo código. Todo debería compilar salvo algunos cambios de sintaxis debido al cambio de componentes.
Digamos que lo que más cambia en todo esto es la forma de trabajar.

Ahora debes pensar que ya no tienes una Base de Datos local, estás trabajando en red y varios equipos pueden estar haciendo lo mismo.
También debes tener en cuenta los datos que solicitas a la base de Datos (SGBD) porque estos deben viajar por la red. Antes podías recorrer una tabla completa sin problemas (porque estaba en local), ahora si lo haces, la tabla completa "viaja" por la red y eso no es recomendable.
Por último debes tener en cuenta que ahora puedes encontrarte con bloqueos (dependiendo de las operaciones que hagas). Dos usuarios que puedan estar modificando el mismo registro o uno que esté leyendo el registro A mientras otro lo modifica.

Neftali [Germán.Estévez] 10-01-2017 10:00:10

Cita:

Empezado por koalasoft (Mensaje 512260)
Antes con el Table buscaba el campo llave para posicionarme en el registro y así poder realizar el cambio .. lo hacía con
Código Delphi [-]
Table1.FindKey([algo])
Alguna idea o voy mal ??

Lo más parecido en ADO, es el comando Locate. Si buscas en la ayuda verás que no es complicado y hay ejemplos.
Te funcionará, pero no es eficiente, porque está pensado para tablas en Local.

ADO funciona tanto con Bases de Datos (locales) como con SGBD (en red) y algunas operaciones están pensadas para los primero y otras para los segundos. Esto tiene que ver con lo comentado en el mensaje anterior. Es cuestión de cambiar de mentalidad.

Locate hace un recorrido secuencial por la tabla, hasta que encuentra el registro deseado. En local no hay problemas, pero en red y con una tabla un poco grande te va a consumir muchos recursos y te va a tardar mucho tiempo. Te va a funcionar, pero creo que en tu nuevo "escenario" no es aconsejable. Para ello puedes usar SQL. Una simple SQL (TADOQuery) utilizando el ID es mucho más eficiente y rápida.

koalasoft 10-01-2017 10:02:38

Cita:

Empezado por Neftali (Mensaje 512262)
En principio, puedes seguir utilizando el mismo código. Todo debería compilar salvo algunos cambios de sintaxis debido al cambio de componentes.
Digamos que lo que más cambia en todo esto es la forma de trabajar.

Ahora debes pensar que ya no tienes una Base de Datos local, estás trabajando en red y varios equipos pueden estar haciendo lo mismo.
También debes tener en cuenta los datos que solicitas a la base de Datos (SGBD) porque estos deben viajar por la red. Antes podías recorrer una tabla completa sin problemas (porque estaba en local), ahora si lo haces, la tabla completa "viaja" por la red y eso no es recomendable.
Por último debes tener en cuenta que ahora puedes encontrarte con bloqueos (dependiendo de las operaciones que hagas). Dos usuarios que puedan estar modificando el mismo registro o uno que esté leyendo el registro A mientras otro lo modifica.

Entiendo lo que comentas y es por eso que solicite sus comentario o sugerencias, ya que es la primra vez que trabajo con BD distribuidas, Sigo buscando la forma de hacer el ejemplo qu mencioné para poder hacer los módulos de ALTA, BAJA, MODIFICACION que usaba en Paradox con el TTable. Si me pudieran orientar con algun tipo de ejemplo o pasos que me faltan seguir.

Gracias !!

koalasoft 10-01-2017 10:14:47

Cita:

Empezado por Neftali (Mensaje 512263)
Lo más parecido en ADO, es el comando Locate. Si buscas en la ayuda verás que no es complicado y hay ejemplos.
Te funcionará, pero no es eficiente, porque está pensado para tablas en Local.

ADO funciona tanto con Bases de Datos (locales) como con SGBD (en red) y algunas operaciones están pensadas para los primero y otras para los segundos. Esto tiene que ver con lo comentado en el mensaje anterior. Es cuestión de cambiar de mentalidad.

Locate hace un recorrido secuencial por la tabla, hasta que encuentra el registro deseado. En local no hay problemas, pero en red y con una tabla un poco grande te va a consumir muchos recursos y te va a tardar mucho tiempo. Te va a funcionar, pero creo que en tu nuevo "escenario" no es aconsejable. Para ello puedes usar SQL. Una simple SQL (TADOQuery) utilizando el ID es mucho más eficiente y rápida.

Intenté hacerlo con el ADOQuery con este código:

Código PHP:

with ADOQuery1 do
  
begin
    Close
;
    
SQL.Clear;
    
SQL.Add('SELECT * FROM CLIENTES ');
    
SQL.Add('WHERE ID_CL LIKE ' +quotedstr('%' DBText1.Caption '%')+' ');
    
Open;
    if 
ADOQuery1.IsEmpty then
    Begin
    showmessage
('No se encuentra registrado, porfavor verifica los datos.');
    
End
     
Else
      
Begin     // si existe modifico el campo
      
AdoTable1.Edit;
      
AdoTable1.FieldByName('NOM_CL').AsString := Edit1.Text;
      
AdoTable1.Post;
      
End;
  
end

Pero no me edita eL campo que estoy especificando !!, Se supone que una vez que hice una consulta, en el DBText1.caption refleja un ID de os registros, en est caso el que consulte, entonces use la condicion de que si el ID que busque y muestra en el DBText lo busque, para que despues yo pueda editar otro campo, en este caso NOM_CL de la misma tabla.

Lo curioso de este es que si me lo edita, pero solo el 1 registro de la tabla, por ejemplo hago la consulta ... en la tabla hay varios ID (1....20) hice una consulta y en el DBTExt me pone el ID consultado, por ejemplo el ID = 4, ahora en el Edit1 coloco un nombre para que actualize el campo "nombre" del ID 4, al darle click actualiza el campo pero NO de ID 4 si no del primer registro.

Estaré haciendo algo mal?

Neftali [Germán.Estévez] 10-01-2017 10:35:41

El código que has colocado no tiene mucho sentido.

1) haces una búsqueda con un ADOQuery. Esa búsqueda encontrará uno o varios registros.
2) Luego compruebas si el Dataset está vacío para saber si ha encontrado algún registro.

(hasta aquí parece correcto)

3) Entonces si ha encontrado algún registro, intentas modificarlo usando un ADOTable, que es otro componente y que no se sabe dónde está apuntando...

(aquí está la incongruencia)

O usas el ADOQuery para todo o el ADOTable para todo, pero estás mezclando ambos.

Por otro lado te recomiendo que utilices parámetros a la hora de montar las sentencias SQL, en lugar de concatenar cadenas.

Código Delphi [-]
  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('SELECT * FROM CLIENTES ');
  ADOQuery1.SQL.Add('WHERE ID_CL LIKE ' +quotedstr('%' + DBText1.Caption + '%')+' ');
  ADOQuery1.Open;

  if ADOQuery1.IsEmpty then Begin
    showmessage('No se encuentra registrado, porfavor verifica los datos.');
  End
  Else Begin     // si existe modifico el campo
    ADOQuery1.Edit;
    ADOQuery1.FieldByName('NOM_CL').AsString := Edit1.Text;
    ADOQuery1.Post;
  End;

koalasoft 10-01-2017 11:22:11

Cita:

Empezado por Neftali (Mensaje 512266)
El código que has colocado no tiene mucho sentido.

1) haces una búsqueda con un ADOQuery. Esa búsqueda encontrará uno o varios registros.
2) Luego compruebas si el Dataset está vacío para saber si ha encontrado algún registro.

(hasta aquí parece correcto)

3) Entonces si ha encontrado algún registro, intentas modificarlo usando un ADOTable, que es otro componente y que no se sabe dónde está apuntando...

(aquí está la incongruencia)

O usas el ADOQuery para todo o el ADOTable para todo, pero estás mezclando ambos.

Por otro lado te recomiendo que utilices parámetros a la hora de montar las sentencias SQL, en lugar de concatenar cadenas.

Código Delphi [-]
  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('SELECT * FROM CLIENTES ');
  ADOQuery1.SQL.Add('WHERE ID_CL LIKE ' +quotedstr('%' + DBText1.Caption + '%')+' ');
  ADOQuery1.Open;

  if ADOQuery1.IsEmpty then Begin
    showmessage('No se encuentra registrado, porfavor verifica los datos.');
  End
  Else Begin     // si existe modifico el campo
    ADOQuery1.Edit;
    ADOQuery1.FieldByName('NOM_CL').AsString := Edit1.Text;
    ADOQuery1.Post;
  End;

Agradezco tu ejemplo y consejos .. me estas dando a entender muchas cosas de cómo va funcionando esto .. solo modifique el código para que en lugar de buscar el dato en un DBText sea en un Label, ya que al momento de hacer la consulta me seguia modificando el primer registro, pero haciendo este cambio ya modifica el que estoy buscando ..

Veo que puedo seguir usando el mismo código pero en lugar de las TTable ahora use ADOQuery, pasó algo curioso .. a hacer la actualización de un campo, recuerdo que en paradox se usaba e flushbuffer para guardar directamente a la tabla, qui ya no se requiere eso en caso de perdida de conección o corte de luz al momento de la transacción?

Neftali [Germán.Estévez] 10-01-2017 14:27:22

Cita:

Empezado por koalasoft (Mensaje 512267)
...a hacer la actualización de un campo, recuerdo que en paradox se usaba e flushbuffer para guardar directamente a la tabla, qui ya no se requiere eso en caso de perdida de conección o corte de luz al momento de la transacción?

Hasta ahora no has usado transacciones.
Estamos haciendo operaciones simples. Si al cortarse la luz se ha hecho estará hecha, si no ha dado tiempo no lo estará.

Otra cosa son transacciones. Es decir, varias operaciones que debes hacer en bloque. O se hacen todas o no se hace ninguna.
Para eso tienes los métodos (relacionados con ADO) de BeginTrans, CommitTrans y RollbackTrans.

Si buscas en la ayuda o en los foros encontrarás ejemplos de utilización.

http://docwiki.embarcadero.com/Libra...ion.BeginTrans
http://docwiki.embarcadero.com/Libra...on.CommitTrans
http://docwiki.embarcadero.com/Libra....RollbackTrans


La franja horaria es GMT +2. Ahora son las 13:12:41.

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