In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Sugerencia para el Equipo de Xailer

Foro público de Xailer en español
Martin Del Angel
Mensajes: 360
Registrado: Mié Dic 03, 2008 5:05 am

Sugerencia para el Equipo de Xailer

Mensaje por Martin Del Angel »

Implementar un Metodo de busqueda incremental pero sobre el array
interno del Dataset y no usando Locate()
Cuando se usa Locate sobre MySql con tablas grandes donde los Queries
son como estos:
cSQL:="SELECT t1.*,t2.PROVEEDOR,t3.STATUS, " + ;
" t4.UNIDAD,t5.FAMILIA,t6.ALMACEN,t7.DEPARTAMENTO,t8.GRUPO,t9. MARCA,t10.TIPOPRODUCTO
FROM tblproductos t1 " + ;
"LEFT JOIN tblproveedores t2 ON t1.PROVEEDOR_ID = t2.PROVEEDOR_ID " + ;
"LEFT JOIN tblstatus t3 ON t1.STATUS_ID = t3.STATUS_ID " + ;
"LEFT JOIN tblunidades t4 ON t1.UNIDAD_ID = t4.UNIDAD_ID " + ;
"LEFT JOIN tblfamilias t5 ON t1.FAMILIA_ID = t5.FAMILIA_ID " + ;
"LEFT JOIN tblalmacenes t6 ON t1.ALMACEN_ID = t6.ALMACEN_ID " + ;
"LEFT JOIN tbldepartamentos t7 ON t1.DEPARTAMENTO_ID =
t7.DEPARTAMENTO_ID " + ;
"LEFT JOIN tblgrupos t8 ON t1.GRUPO_ID = t8.GRUPO_ID " + ;
"LEFT JOIN tblmarcas t9 ON t1.MARCA_ID = t9.MARCA_ID " + ;
"LEFT JOIN tbltipoproducto t10 ON t1.TIPOPRODUCTO_ID =
t10.TIPOPRODUCTO_ID " + ;
"WHERE t1.EMPRESA_ID="+ VALTOSTR(APPDATA:EMPRESA_ID) + ;
" AND t1.SUCURSAL_ID=" + VALTOSTR(APPDATA:SUCURSAL_ID) + " ORDER BY
t1.DESCRIPCION "
son una lentitud ya que cada letra que tecleas se ejecuta un query, por
ejemplo: si deseo buscar la palabra HERRAMIENTA , entonces empiezo a
teclar la letra "H" despues que la he tecleado se ejectuta un query
sobre la base de datos buscando la letra H , se imaginan con el Query de
Arriba con 30,000 productos, 2 segundos para posicionarse en la letra
"H" , despues tecleo la "E" y otros 2 segundos y asi sucesivamente.
Pero lo grave es que si tecleo rapidamente la palabra HERRAMIENTA Xailer
2 marca error (aclaro usando MySql) :
Commands out of sync; you can't run this command now [#2014]
antes con la version 1.98 no salia este error , debido a que lo podia
atrapar , con este codigo:
#include "Xailer.ch"
//---------------------------------------------------------- --------------------
// SOPORTE CONEXION DATA SOURCE MySQL
//---------------------------------------------------------- --------------------
#define DK_DEFAULT_OR_NOT DEFAULT // Why ? :'(
CLASS TMySQLDataSource FROM XMySQLDataSource
METHOD Execute( cCmdMySQL, cEOpe, @aData, @aHeaders )
* METHOD File( cLikeVTabName )
ENDCLASS
METHOD Execute( cCmdMySQL, cEOpe, aData, aHeaders ) CLASS TMySQLDataSource
Local oE, lSuccess, lDone := TRUE
Application:oMainForm:oTimerMYSQL:lEnabled:=.f.
while( lDone )
lDone := FALSE
TRY
lSuccess := Super:Execute( cCmdMySQL, cEOpe, @aData, @aHeaders )
// Now the integrity of your DATA is PROBLEM of MySQL. :) :) :)
CATCH oE
lSuccess := FALSE
SWITCH( oE:GenCode )
CASE 2005 // MySQL UNKNOWN_HOST
CASE 2006 // MySQL server has gone away
Waiton("Conectando con Base de Datos ....")
::Disconnect(); ProcessMessages(); Sleep( 10 )
lDone := lSuccess := ::Connect(); ProcessMessages(); Sleep(
10 )
waitoff()
if( !lSuccess )
DEFAULT cEOpe TO ''
::CheckError( cEOpe + ' => Error de Re-Conexion' )
endif
EXIT
CASE 2013 // MySQL server lost
MSGSTOP('Se perdió la Conexión con Servidor')
Waiton("Estableciendo Conexión con Base de Datos ....")
::Disconnect(); ProcessMessages(); Sleep( 10 )
lDone := lSuccess := ::Connect(); ProcessMessages(); Sleep(
10 )
waitoff()
if( !lSuccess )
DEFAULT cEOpe TO ''
::CheckError( cEOpe + ' => Error de Re-Conexion' )
endif
EXIT
CASE 2014 // MySQL Command Out if Sync
ProcessMessages(); Sleep( 10 )
EXIT
CASE 1053 // Desconexion de servidor en proceso
CASE 1152 // Conexión abortada
DK_DEFAULT_OR_NOT // What ??? 8-)
WITH OBJECT oE
:Operation := :ProcName := ProcName( 1 )
:ProcLine := ProcLine( 1 )
END
Throw( oE )
END
END
enddo
Application:oMainForm:oTimerMYSQL:lEnabled:=.t.
RETURN lSuccess
Con la Version 2 ya no funciona , no atrapa los errores (aclaro el
comando TRY CATCH funcionan , hice pruebas en otro modulo y funcionan ,
pero en el codigo de arriba el EXECUTE toma el control de los errores ,
aunque le pongas lo que pongas en la propiedaD lAbortOnErrors pasa lo mismo
Debido a que estoy presionado sobre un proyecto, me di la tarea de
implementar otra manera de hacer busquedas incrementales con MySql
evitando usar el Metodo LOCATE.
Tengo 75% de avance y con resultados muy buenos:
Creo un array utilizando el Metodo GETROWS() del DataSet ,el cual es una
fiel copia del array interno que maneja el DATASET , despues sobre este
array hago la busqueda y me funciona perfecto y super rapido sin
importar a que la velocidad de tecleo.
Desventajas:
Cada Vez que actualize el DataSet tengo que volver a actualizar el array
con GETROWS como por ejemplo: cuando se agregan, eliminan , modifican
filas o registros del DATASET
Sugerencia:
1. Crear una propiedad en el DataSet que podria ser : aRecords
que fuese una matriz multi-dimensional con todos los registros del
dataset y que cada vez que se actualize el DataSet se actualize en forma
dinamica esta matriz.
2. Crear un Metodo que busque sobre el array interno del dataset
con tablitas pequeñas de 50 registros y que no esten relacionadas la
busqueda incremental usando LOCATE funciona bien siempre y cuando no
teclee rapido , porque si lo hago pasa el error "Commands out of sync;
you can't run this command now [#2014]" .
Saludos....
Responder