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.

OT: Cambiando el chip de xBase a Sql

Foro público de Xailer en español
jose.luis
Mensajes: 1633
Registrado: Vie Oct 14, 2005 10:56 pm

OT: Cambiando el chip de xBase a Sql

Mensaje por jose.luis »

Hola a todos,
Resulta que ando adaptando código de xbase (orientado a DBF's) hacia
código SQL (concretamente Sql Server 2000).
Bien.. tengo la siguiente duda de como implementar el proceso. Os lo
explico.
Situación: de una lista arbitraria de clientes necesitamos extraer la
información de los 7 últimos albaranes (de cada cliente, claro). La
información consistirá en el Código del cliente, número de albarán, total
albarán, fecha albarán y para cada linea del albarán, código del
artículo, descripción, cantidad, precio y subtotal linea.
Las tablas disponibles son (simplificado):
Cabeceras
Campo Tipo Pk
cNumAlb Char Si
cCodCli Char Si
dFecAlb Date No
nTotal Numeric No
Lineas
Campo Tipo Pk
cNumAlb Char Si
cCodArt Char No
cDesArt Char No
nLinea Autocount Si
nCantidad Numeric No
nPrecio Numeric No
Y la lista de clientes de los cuales se quiere la información está
guardada en una matriz unidimensional con un número indeterminado de
elementos.
Este problema, a lo xbase, podría ser resuelto así (es solo un ejemplo
que puede tener errores)
aClientes := {"00001","00033",.....,"09933"}
FOR EACH cliente IN aClientes
// ---> RecordSet
oAlbaranes := TraeDatos("SELECT TOP 7 * FROM CABECERAS WHERE cCodCli
= '"+cCliente+"' ORDER BY cNumAlb DESC;")
oAlbaranes:GoTop()
DO WHILE !oAlbaranes:Eof()
// ---> RecordSet
oLineas := TraeDatos("SELECT * FROM LINEAS WHERE cNumAlb =
'"+oAlbaranes:cNumAlb+";")
oAlbaranes:GoTop()
DO WHILE !oLineas:Eof()

//--------->
//---------> Aquí vendría nuestro código
//--------->


oLineas:Skip(+)
ENDDO
oAlbaranes:Skip(+)
ENDDO
NEXT
Este sistema xBase puede utilizarse contra un sistema Sql. Y funciona.
Pero se obtienen unos resultados pobres o intolerables cuando la lista de
clientes comienza a subir. La explicación podría venir por el hecho de
que para cada cliente se están realizando 8 consultas al servidor. Si
tenemos 500 clientes que consultar (algo que se puede considerar
habitual) nuestro equipo se queda con un consumo de CPU al 100x100 o casi
y al servidor Sql lo estamos saturando.
En fin... para los que saben de esto...
¿Como podríamos optimizar esto?
Yo había pensado en algo como esto (simplificado):
SELECT cabeceras.cnumalb, cabeceras.ccodcli, lineas.cref
FROM CABECERAS
RIGHT JOIN LINEAS
on cabeceras.cnumalb = lineas.cnumalb
WHERE cabeceras.ccodcli = IN ( ... lista de clientes ... )
Sin embardo, me saca todos los albaranes da lista de clientes. Con esta
otra instrucción:
SELECT TOP 7 cabeceras.cnumalb, cabeceras.ccodcli, lineas.cref
FROM CABECERAS
RIGHT JOIN LINEAS
on cabeceras.cnumalb = lineas.cnumalb
WHERE cabeceras.ccodcli = IN ( ... lista de clientes ... )
Me saca 7 filas en total... pero a mi me interesan 7 documentos por
cliente.
Bueno...a ver si alguien me puede echar una manita...
Saludos y gracias,
José Luis Capel
Responder