Comparar Tablas de MySQL

369 views
Skip to first unread message

Jose Oscar Vogel

unread,
Aug 31, 2011, 9:32:11 AM8/31/11
to publice...@googlegroups.com
Debido a que realizo desarrollos para varios clientes, con distintas base de datos y distintas estructuras, y voy modificando la estructura de las tablas en mi computadora de desarrollo que luego tengo que llevar a los clientes esas modificaciones me surgió la idea de desarrollar algo para comparar las estructuras de las tablas, esto es lo que comparto con ustedes.-

Acepto ideas de mejoras (se que seguramente tiene que haberlas) ya que fue el desarrollo de una mañana y seguramente se me pasó algunas cosas por alto.-

La idea es la siguiente:
1) Ejecutan el programa en la computadora de desarrollo y al hacer clic sobre el boton exportar les genera unas tablas libres con la estructura de todas las tablas.-
2) En la maquina del cliente abren el programa e importan esas tablas y hacen clic sobre el boton comparar.-
3) Esto les genera un reporte con los campos que faltan agregar y las diferencias que hubieren de los campos existentes.-

Falta agregar:
1) Que controle los campos eliminados en la maquina de desarrollo y que todavia se encuentre en la maquina del cliente.-
2) .... todo lo que quieran agregar.-

Unicamente funciona para MySQL que es el motor que utilizo.-

Saludos Oscar

--
Prof. Jose Oscar Vogel
Garuhapé - Misiones
CP 3334
Cel: 03743-15667526
MSN: oscar...@gmail.com
Twitter: @ovogel23
Facebook: oscarvogel


ActTabla.7z

Marco Plaza

unread,
Aug 31, 2011, 10:32:05 AM8/31/11
to publice...@googlegroups.com

Gracias por el aporte Oscar, yo hice algún tiempo atrás uno similar para tablas DBF.. hay similares en internet pero no me cuadró ninguno... dentro de lo que puedes añadirle veo que puede ser:

-al comparar, generar un procedimiento con los alter table necesarios que añadan, modifiquen columnas o eliminen columnas marcadas como innecesarias, que deben existir explicitamente en otra tabla
-procedimientos pre eliminacion de columnas
-procedimientos post proceso de actualización de nuevas columnas
-guardar una tabla con la imagen de la bd certificada con número de versión que permita certificar la bd en uso


Saludos.



Jose Oscar Vogel

unread,
Aug 31, 2011, 10:34:48 AM8/31/11
to publice...@googlegroups.com
ok, gracias por los aportes, seguiré modificando y agregando funcionalidades, ya que me sirve a mi tambien

saludos

sergio garcia

unread,
Aug 31, 2011, 11:26:05 AM8/31/11
to publice...@googlegroups.com

Muy buen aporte lo vamos a revisar y se le podemos agregar algo lo subo.

 

 

______________________________________

Sergio A. García
Gerencia
in...@magicsoft.com.gt

Magicsoft de Guatemala
30 Avenida A 17-80 Zona 7 Villa Linda I, Guatemala / 9 calle 7-65 Zona 1, Jutiapa
Tlf: 5527-4094 · Fax: 7844-3805
in...@magicsoft.com.gt · www.magicsoft.com.gt  skype    

magicblancopecoNo me imprimas si no es necesario. Protejamos el medio ambiente

image001.png
image002.png
image003.gif

Jose Oscar Vogel

unread,
Aug 31, 2011, 2:07:49 PM8/31/11
to publice...@googlegroups.com
Gracias Sergio, cualquier aporte bienvenido sea

Saludos 

image003.gif
image001.png
image002.png

Daniel Del Giudice

unread,
Aug 31, 2011, 4:14:04 PM8/31/11
to Comunidad de Visual Foxpro en Español
Puedes ponerle número de versión a tu aplicación y cada vez que entres
verificas si la versión del exe se corresponde con el número de
versión que tienes guardada en algún lugar, si difieren entonces
ejecutas automáticamente tu rutina, la cual debe incluir al final
guardar el presente número de versión. Esto te permite subir una
aplicación vía FTP y que tus clientes la bajen si tener que
preocuparse por la estructura de datos, que se actualiza solita.

;-)

Daniel Del Giudice
Santiago del Estero
Argentina

Jose Oscar Vogel

unread,
Aug 31, 2011, 4:15:53 PM8/31/11
to publice...@googlegroups.com
Bien ahi Daniel, me gusta la idea, la trataré de implementar y te comento como queda

gracias

Daniel Del Giudice

unread,
Sep 1, 2011, 8:16:47 AM9/1/11
to Comunidad de Visual Foxpro en Español
Esta es la rutina que yo uso. Te la paso tal cual la tengo, así que si
necesitas alguna aclaración te la hago sin problemas. Fijate que en la
primera parte hago lo rutinario como controlar tablas, campos e
índices nuevos y luego tengo una parte donde hago cosas específicas
según se necesite en cada versión. Hay veces que vas a tener que hacer
cosas fuera de lo habitual. Tengo una tabla libre para las tablas,
otra para los campos y otra para los índices, y todas van dentro del
exe con la version nueva.
Cuando pongo el asterisco es porque esa parte de la rutina ya no la
necesito más, ya que todos los clientes tienen una versión posterior a
donde se necesitaba ese cambio, pero las dejo ahí para referencias
futuras.


_exact = set("exact")
set exact on
select 0
use indices noupdate
select 0
use campos noupdate
select 0
use tablas noupdate

_error = .f.
* Crea tablas
scan
_tabla = trim(tabla) + ".DBF"
if not file(_tabla)
auxiliar = sys(3)
auxiliar1 = auxiliar + ".DBF"
auxiliar2 = auxiliar + ".FPT"
select campos
copy to (auxiliar1) fields except tabla for tabla = tablas.tabla
select 0
create (_tabla) database zp from (auxiliar1)
use
erase (auxiliar1)
erase (auxiliar2)
select tablas
endif
endscan

* Crea campos
scan && tablas
select 0
try
use (tablas.tabla) alias archdbf exclusive
catch to oerr
messagebox("La tabla " + trim(tablas.tabla) + " está en uso.
Ciérrela y vuelva a intentar. (1)", 16, "Error")
_error = .t.
finally
endtry

if _error
exit
else
select campos
* Recorro cada campo que debería tener la tabla
scan for tabla = tablas.tabla
select archdbf
_haycampo = .f.
* Recorro los campos de la tabla para tratar de encontrar el
campo actual
for j = 1 to fcount()
if field(j) = trim(campos.field_name)
_haycampo = .t.
exit
endif
endfor
if not _haycampo
_nombre = trim(campos.field_name)
do case
case campos.field_type = "C"
_propiedades = "C (" + ltrim(str(campos.field_len,3)) + ")"
case campos.field_type = "N"
_propiedades = "N (" + ltrim(str(campos.field_len,3)) + ","
+ ltrim(str(campos.field_dec,3)) + ")"
otherwise
_propiedades = campos.field_type
if campos.field_type = "I" and campos.field_step > 0
_propiedades = _propiedades + " AUTOINC"
endif
endcase
alter table (tablas.tabla) add column (_nombre) &_propiedades
endif
select campos
endscan
select archdbf
use
endif
select tablas
endscan

* Crea índices
if not _error
select tablas
scan
select 0
try
use (tablas.tabla) alias archdbf exclusive
catch to oerr
messagebox("La tabla " + trim(tablas.tabla) + " está en uso.
Ciérrela y vuelva a intentar. (2)", 16, "Error")
_error = .t.
finally
endtry

if _error
exit
else
select indices
scan for tabla = tablas.tabla
select archdbf
_hayindice = .f.
for j = 1 to tagcount()
if tag(j) = trim(indices.indice)
if key(j) # trim(indices.expresion)
do indexa
endif
_hayindice = .t.
exit
endif
endfor
if not _hayindice
do indexa
endif
select indices
endscan
select archdbf
use
endif
select tablas
endscan
endif

if not _error
* Borra archivos de detalle
select distinct estacion from registro into cursor pcs
scan for not empty(estacion)
arch = sys(5) + curdir() + "COMPUTADORAS\" + trim(estacion) + "\"
+ "MOSTRADOR_DETALLE1.DBF"
if file(arch)
erase (arch)
endif
arch = sys(5) + curdir() + "COMPUTADORAS\" + trim(estacion) + "\"
+ "MOSTRADOR_DETALLE2.DBF"
if file(arch)
erase (arch)
endif
arch = sys(5) + curdir() + "COMPUTADORAS\" + trim(estacion) + "\"
+ "PEDIDO_ACTUAL_DETALLE.dbf"
if file(arch)
erase (arch)
endif
arch = sys(5) + curdir() + "COMPUTADORAS\" + trim(estacion) + "\"
+ "FCOMPRA_ACTUAL_DETALLE.DBF"
if file(arch)
erase (arch)
endif
arch = sys(5) + curdir() + "COMPUTADORAS\" + trim(estacion) + "\"
+ "REMITO_INTERNO.DBF"
if file(arch)
erase (arch)
endif

* Rutina que cambia el nombre de la columna vehiculo por subrubro
(Versión 2.20.0)
arch = sys(5) + curdir() + "COMPUTADORAS\" + trim(estacion) + "\"
+ "vista_precios.DBF"
if file(arch)
select 0
use (arch)
locate for columna = "vehiculo"
if found()
replace columna with "subrubro"
endif
use
select pcs
endif
* Fin rutina
endscan

* Rutina para cambiar la longitud de ganancia de 999 a 999.999
* Puede eliminarse a partir de la versión 2.18.35
* use precios exclusive
* if fsize("ganancia") = 3
* alter table precios alter column ganancia n(7,3)
* endif
* use
* Fin rutina *

* Rutina para cambiar el nombre del archivo "logo pedido.bmp" a
logo_pedido.bmp
* Puede eliminarse a partir de la versión 2.18.35
* if file("logo pedido.bmp")
* rename "logo pedido.bmp" to "logo_pedido.bmp"
* endif
* Fin rutina *

* Rutina que actualiza el campo estadistic en la tabla usuarios
(Versión 2.20.0)
* use usuarios exclusive
* locate for upper(trim(usuario)) = "ADMINISTRADOR"
* replace estadistic with .t., bancos with .t., cheques with .t.
* use

* Rutina que pone la fecha en Notas de crédito (Versión 2.20.0)
* Esto facilita sumar totales por producto sin tener que ver la
fecha en la tabla notas_credito
* use notas_credito_detalle exclusive
* if empty(fecha)
* use notas_credito order ncsec exclusive in 0
* set relation to ncsec into notas_credito
* replace fecha with notas_credito.fecha for empty(fecha)
* use in notas_credito
* endif
* use

* Rutina para eliminar campo mercaderia y devolucion_dinero de
notas_credito
* use notas_credito exclusive
* if fsize("mercaderia") > 0
* replace all efectivo with efectivo + mercaderia +
devolucion_dinero
* alter table notas_credito drop column mercaderia
* alter table notas_credito drop column devolucion_dinero
* endif
* use

* Rutina para eliminar campos innecesarios en la caja
* use cajas_detalle exclusive
* if fsize("clisec") > 0
* alter table cajas_detalle drop column clisec
* endif
* use
* Fin rutina

* Rutina para pasar RECSEC a tipo autoincrement (Versión 2.22.4)
* arch = sys(3)
* arch1 = arch + ".DBF"
* arch2 = arch + ".FPT"
* use recibos exclusive
* copy structure extended to (arch)
* select 0
* use (arch)
* locate for field_name = "RECSEC"
* _fn = field_next
* use
* erase (arch1)
* erase (arch2)
* select recibos
* if _fn = 0
* replace all recsec with recno()
* go bottom
* r = recsec + 1
* alter table recibos alter column recsec i autoinc nextvalue r
* endif
* use
* Fin rutina

* Rutina para pasar el campo de impresion por impresora o
controlador
* de ser general a establecerse por estación
use registro again
locate for clave = "IMPRIMIR_CF" and not empty(estacion)
if not found()
locate for clave = "IMPRIMIR_CF"
n = numero
select distinct estacion where not empty(estacion) from registro
into array estaciones
for j = 1 to alen(estaciones)
append blank
replace clave with "IMPRIMIR_CF", numero with n, estacion with
estaciones(j)
endfor
endif
use
* Fin rutina

* Rutina para pasar el campo concepto de 1 a 2 posiciones numéricas
use stock exclusive
if fsize("concepto") = 1
alter table stock alter column concepto n(2,0)
endif
use
* Fin rutina

* Rutina para corregir lineas_detalle_x contenía las líneas del
Remito
* ahora contiene las líneas del presupuesto
x = lee_registro("LINEAS_DETALLE_X", "N", 12, .f.)
=lee_registro("LINEAS_DETALLE_R", "N", x, .f.))

* Anteriormente la opción decía: "Imprimir sólo por impresora" =
Verdadero o Falso
select registro
locate for clave = "IMP_PRESUP_IMPRESORA"
if found()
if logico
=escribe_registro("IMPRIMIR_CF_PTO", "N", 2, .t.) && Impresora
else
=escribe_registro("IMPRIMIR_CF_PTO", "N", 1, .t.) && Controlador
Fiscal
endif
delete for clave = "IMP_PRESUP_IMPRESORA"
endif
* Fin rutina

* Rutina para encriptar las claves
* Puede eliminarse a partir de la versión 2.23.9
* select 0
* use usuarios
* scan for not encriptado
* replace ;
contraseña with encr(upper(trim(contraseña))), ;
encriptado with .t.
* endscan
* use
* Fin rutina

* Rutina para indexar los campos concepto e id en las ubicaciones
del stock
select 0
use ubicaciones
scan
if color = 0
do case
case recno() = 1
c = rgb(193,255,132)
case recno() = 2
c = rgb(183,183,255)
case recno() = 3
c = rgb(255,255,157)
case recno() = 4
c = rgb(255,177,140)
case recno() = 5
c = rgb(255,174,255)
endcase
replace color with c
endif
arch = trim(nombre)
select 0
use (arch) exclusive
if tagno("concepto") = 0
index on concepto tag concepto
endif
if tagno("id") = 0
index on id tag id
endif
use
select ubicaciones
endscan
use
* Fin rutina

* Rutina para agregar los bancos más conocidos
select 0
use bancos
if reccount() = 0
append blank
replace nombre with "HSBC"
append blank
replace nombre with "CIUDAD DE BUENOS AIRES"
append blank
replace nombre with "COLUMBIA"
append blank
replace nombre with "COMAFI"
append blank
replace nombre with "CREDICOOP"
append blank
replace nombre with "GALICIA"
append blank
replace nombre with "HIPOTECARIO"
append blank
replace nombre with "MACRO BANSUD"
append blank
replace nombre with "NACION"
append blank
replace nombre with "PATAGONIA"
append blank
replace nombre with "BBVA FRANCES"
append blank
replace nombre with "BNP PARIBAS"
append blank
replace nombre with "CITIBANK"
append blank
replace nombre with "STANDARD BANK"
append blank
replace nombre with "SANTANDER RIO"
append blank
replace nombre with "BSE SANTIAGO DEL ESTERO"
append blank
replace nombre with "ITAU"
append blank
replace nombre with "PROVINCIA DE CORDOBA"
append blank
replace nombre with "PROVINCIA DE BUENOS AIRES"
endif
use
* Fin rutina

* Rutina que actualiza el campo estadistic en la tabla usuarios
(Versión 2.20.0)
select 0
use usuarios exclusive
locate for upper(trim(usuario)) = "ADMINISTRADOR"
replace mod_stock with .t.
use

* Rutina que pone la fecha en el detalle de Remitos (Versión
2.25.10)
* esto facilita sumar totales por producto sin tener que ver la
fecha en la tabla remitos
use remitos_detalle exclusive
if reccount() > 0
go bottom
if empty(fecha)
use remitos order rtosec exclusive in 0
set relation to rtosec into remitos
replace fecha with remitos.fecha for empty(fecha)
use in remitos
endif
endif
use

* Rutina que ingresa el campo "usuario" en las distintas ubicaciones
(depósitos o sucursales)
use ubicaciones
if reccount() > 0
scan
arch = trim(nombre)
select 0
use (arch) exclusive
if fsize("usuario") = 0
alter table (arch) add column usuario c(15)
endif
use
select ubicaciones
endscan
endif
use

select 0
use comisiones
if reccount() < 5
for j = reccount()+1 to 5
append blank
endfor
endif
use
endif



if _error
messagebox("Error al actualizar los datos. Cierre el sistema en
todas las estaciones así como el Controlador Fiscal. Luego intente
nuevamente.", 16, "Error")
quit
else
select registro
=escribe_registro("ULTIMA_VERSION_USADA", "C",
_version_sistema, .f.)
=escribe_registro("ULTIMA_VERSION_USADA", "F", date(), .f.)
* Pone este valor en falso, de manera que cualquier estación al
entrar va a intentar enviar la información del negocio
=escribe_registro("ULTIMA_VERSION_USADA", "L", .f., .f.)
do actualiza_datoszp
endif

close tables all
close databases
set exact &_exact
return

procedure indexa
exp = trim(indices.expresion)
ind = trim(indices.indice)
index on &exp tag &ind
return


* Rutina para cambiar el tipo de campo
*use articulos exclusive
*if type("grupo") = "N"
* alter table articulos alter column grupo c(3)
* replace all grupo with alltrim(grupo)
* replace grupo with "" for trim(grupo) = "0"
*endif

* Rutina para cambiar la longitud de un campo
*use clientes exclusive
*if len(nombre) = 30
* alter table clientes alter column nombre c(50)
*endif
*IF FSIZE("ganancia") = 3
*endif

* Rutina para eliminar un campo
*use notas_credito exclusive
*if not empty(field("neto1"))
* alter table notas_credito drop column neto1
*endif

Jose Oscar Vogel

unread,
Sep 1, 2011, 8:21:22 AM9/1/11
to publice...@googlegroups.com
si, esta perfecto, yo tengo una rutina similar con tablas libres, el tema es que lo que yo postee era para MySQL

saludos y gracias

Daniel Del Giudice

unread,
Sep 1, 2011, 11:46:39 AM9/1/11
to Comunidad de Visual Foxpro en Español
Jeje, me olvidé. Cuando la tengas pasamela por favor, que pronto estoy
por migrar a MySQL justamente.

Saludos cordiales,

Daniel
Reply all
Reply to author
Forward
0 new messages