Alguna idea para realizar consulta SQL dependiendo de un cursor de VFP

302 views
Skip to first unread message

Juan Cueli

unread,
Dec 2, 2021, 8:12:17 AM12/2/21
to Comunidad de Visual Foxpro en Español
Hola a todos, hay que algo que me gustaria hacer y realmente no se me ocurre una forma optima para hacerlo. Actualmente uso FoxyDB para las conexiones con SQL y quiero hacer algo como esto (es solo un ejemplo, pero es basicamente esto lo que quiero hacer):

Tengo el siguiente cursor en VFP
select .t. as lsel,;
idcodigo;
from mitabla
into cursor c_codsel Readwrite

y luego creo la siguiente variable con la consulta sql
TEXT to lnPersona noshow
SELECT  idcodigo  ,
Ltrim(Rtrim(Ltrim(Rtrim(sAPellido1))+Isnull(' '+Ltrim(Rtrim(sApellido2)),'')+', '+Ltrim(Rtrim(sNombres)))) as sEmpleado
from Persona
ENDTEXT

oConn.Query( lnPersona  ,"c_DatosPersona","Persona")
(Obviamente para este momento ya tengo la conexion creada con foxyDB)

La idea es que mi cursor c_CodSel puede traer una cantidad x de registro y el usuario puede cambiar el campo lsel de .t. a .f. y quisiera que la consulta que realizo en SQL solo traiga los codigos que en el cursor anterior esten .t.

Esto lo he hecho utilizando el in de sql. Por ejemplo
hago un scan en el cursor c_COdSel, guardo los codigos en una variable que se llama lcCodsel separado por coma y funciona a la perfeccion

from Persona
where idCodigo in (<<lcCodSel>>)

Cual es mi inconveniente en este momento, que el cursor de VFP puede tener 10 mil, 12 mil, incluso 100 mil registros y el usuario de diferentes formas puede seleccionar solo algunos de esos registros y esos son los que me interesa traer directamente desde SQL. 
  1. Hay alguna forma mas optima para hacer esto o seria obligatoriamente usar el in????
  2. Este in, tiene alguna limitante de cantidad de registros que puedo enviar??? Si no me equivoco, el inlist de VFP (que seria mas o menos esto mismo en SQL) creo que tiene un limite de 24 parametros a enviar.

Espero que hayan entendido mi duda. Gracias por todo


HernanCano

unread,
Dec 2, 2021, 10:51:37 AM12/2/21
to Comunidad de Visual Foxpro en Español
Con respect5o a límite en la cantidad de parámetros en la cláusula IN:


Para MariaDB v10.3.22, MySQL v5.6.27 y MySQL v5.7 sólo encontré ésto:


En MySQL parece que no hay un límite específico. Remítete a la propiedad Max_Allowed_Packet:









Para Firebird tampoco se menciona:



Para SQL Server en la sección "Passing the List as Many Parameters" se trata un límite:


Para PostgreSQL se menciona que tampoco hay:


Para SQLite se menciona que tampoco hay, pero se recuerdan buenas prácticas a seguir (límite en la longitud de una cadena alfanumérica):


Esta investigación si bien la hice yo, también pudiste haberla hecho tú. Te recuerdo que Internet es una muy buena fuente de información, especialmente para lo que consultas.

Esta consulta tuya ¿a qué motor iba dirigida?

Antonio Meza

unread,
Dec 2, 2021, 1:24:11 PM12/2/21
to Comunidad de Visual Foxpro en Español
Recuerda que puedes hacer un Select sobre otro Select, de hecho en el primer link que te envió Hernan viene el ejemplo que necesitas 

SELECT * FROM table1 WHERE table1.id IN ( SELECT id from table2 )

Desde luego tienes que ajustar a tus tablas y campos.

saludos
Antonio Meza

Juan Cueli

unread,
Dec 2, 2021, 3:04:14 PM12/2/21
to Comunidad de Visual Foxpro en Español
Hola, gracias por los link, estoy trabajando con SQL server y me parece que esa pagina la habia visto, pero para ser sincero, no habia visto dicho la parte que mencionas, Muchas gracias por los links. De todas formas dudo que vaya a optar por esta opcion, aunque investigando creo que me puede servir si uso un XML, ya que no quiero hacer un in que tenga tantos parametros, como decia, pueden llegar hasta 10 mil. Ya vere como lo resuelvo, gracias

Juan Cueli

unread,
Dec 2, 2021, 3:06:59 PM12/2/21
to Comunidad de Visual Foxpro en Español
Sobre esta idea, es lo que me gustaria hacer, pero el problema es que el select dentro del in (el de table2) no se encuentra en SQL, se encuentra en un cursor de VFP. A lo mejor estoy preasumiendo porque nisiquiera lo probe, pero me imagino que no puedo poner simplemente in(<<select id from table2>>) tomando encuenta que table2 se encuentra en un cursor de vfp. De todas formas, seguire viendo opciones, y si no, pues entonces vere como adapto lo que estoy haciendo a algo mas funcional. Gracias nuevamente.

Antonio Meza

unread,
Dec 2, 2021, 3:20:56 PM12/2/21
to Comunidad de Visual Foxpro en Español
Definitivamente no puedes mesclar un cursor en una sentencia SQL hacia un servidor de base de datos.

Lo que no logro entender de donde llenas este cursor que luego quieres que te sirva de filtro para la consulta al servidor?

Tengo el siguiente cursor en VFP
select .t. as lsel,;
idcodigo;
from mitabla
into cursor c_codsel Readwrite

saludos
Antonio Meza

Juan Cueli

unread,
Dec 2, 2021, 3:58:50 PM12/2/21
to Comunidad de Visual Foxpro en Español
Claro, te explico...el cursor c_codsel lo cargo en el init y lo pongo en un grid...ese cursor el usuario puede marcar y desmarcar lo que necesite, y luego con esa seleccion me interesa traer la informacion que necesita el usuario desde SQL.
Por ejemplo, en la c_CodSel es una tabla maestra donde cada persona esta solo una vez. Luego el usuario indica a que Personas de c_CodSel le interesa imprimir el detalle que se encuentra en otra tabla.

Antonio Meza

unread,
Dec 2, 2021, 4:44:31 PM12/2/21
to Comunidad de Visual Foxpro en Español
Me dices que un usuario puede ver 10mil o 12 mil registros en un grid o hasta 100mil ? creo que por ahí viene el problema no crees? en mostrar tantos registros al usuario y por eso tienes el problema de usar la clausula IN con parámetros para obtener el cursor del servidor.

Me gustaría apoyarte pero necesitaría entender realmente que problemas tienes porque al parecer no lo estas atacando correctamente, posiblemente en DBF no es problema pero para un servidor de base de datos todo cambia.

saludos

Juan Cueli

unread,
Dec 4, 2021, 11:34:05 AM12/4/21
to publice...@googlegroups.com

Hola, gracias por tu ayuda, lo que pasa es que estoy desarrollando un sistena de pago de nóminas y al momento de enviar los volantes de pago, quiero que el usuario selecciona a que empleados le va a enviar sus volantes de pago. Entonces así como una empresa puede tener 100 o 200 empleados, tambor hay los que tienen 10 mil empleados (y aunque aun no ha pasado, también pueden haber muchos más) entonces el empleado puede seleccionar uno a uno, o decir que marque a los de x oficina y así sucesivamente.... Pero creo que lo mejor para este caso es abordar este caso de otra forma pues veo que así hacerlo como me gustaría seria complicado.


La idea de que el usuario pueda  enviar estos volantes por correos a algunos empleados es porque he tenido casos de que por alguna razón, a algunos no les llega y tienen que enviárselo a esas personas nuevamente. Pero ese ya es otro tema que probaré con csFoxySMTP

De todas formas, gracias por tu pronta respuesta 

--
Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/613632c8-2b8d-4f2a-81cc-5ce19c25d6f9n%40googlegroups.com.

Francisco Lorente

unread,
Dec 4, 2021, 12:45:27 PM12/4/21
to Comunidad de Visual Foxpro en Español
Hola, Juan

¿No prodrías agregar un campo a la tabla SQL que te sirva para "marcar" los registros que quieras incluír en la consulta SQL?

Algo así como: (yo no trabajo con FoxyDB por eso utilizo las funciones SQL de FoxPro sobre MariaDB)

    Alter Table Persona Add isselected TinyInt(1) Unsigned Null Default 0, Add Index isselected (isselected)

Luego cuando tengas el primer cursor generado con tu código:

    Select .T. As lsel, idcodigo From mitabla Into cCursor c_codsel Readwrite

realizas un scan actualizando el campo isselected en la tabla SQL:

        Select c_codsel
        Scan
        Text To m.lcSentenceSQL TextMerge NoShow PreText 7
            Update persona Set isselected = 1 Where idcodigo = <<c_codsel.idcodigo>>
        EndText
            SQLExec(tuconexion, m.lcSentenceSQL)
        EndScan


armas tu segunda consula filtrando por el campo isselected para obtener los registros deseados:

    SQLExec(tuconexion, 'Select * From persona Where isselected = 1', 'c_DatosPersona')

cuando termines, vuelves a dejar desactivado el campo isselected para su uso en futuras consultas:

    SQLExec(tuconexion, 'Update persona Set isselected = 0 Where isselected = 1')


Espero que esta idea te sirva.

Saludos.
Francisco Lorente.
Murcia. España.

Edwin Duran

unread,
Dec 4, 2021, 4:24:46 PM12/4/21
to Comunidad de Visual Foxpro en Español
Por que no Imprimes por departamento o por empresa
Reply all
Reply to author
Forward
0 new messages