Se puede recorrer los registros con Do while o Scan ? en MySQL

2,614 views
Skip to first unread message

Saúl Piña

unread,
Sep 22, 2014, 10:39:44 AM9/22/14
to publice...@googlegroups.com
Saludos, quiero dejar de hacer estas rutinas de recorrer los registros por medio de una condicion para guardar los resultados en otra tabla, y estoy acostumbrado a hacerlo en dbf con la ayuda de prg, por ejemplo la siguiente rutina realiza un conteo de registros segun condicion y guarda los totales en una tabla,

Esta misma rutina, me gustaria empezar a trabajr con HeidiSQL para dejar poco a poco las dbf's de vfp.  gracias.

SET EXACT ON

*OPEN DATABASE bd.dbc
USE Lista1 IN 0
SET FILTER TO NOT EMPTY(IMPAGO)
GO TOP

USE resumen IN 0

DO WHILE !EOF()
SELECT lista
COUNT FOR ben.letra==resumen.letra AND ben.seccion=resumen.seccion TO meta1
COUNT FOR ben.letra==resumen.letra AND ben.seccion=resumen.seccion AND estatus=1 TO ent1
COUNT FOR ben.letra==resumen.letra AND ben.seccion=resumen.seccion AND estatus>1 TO est1
x1=ent1+est1
x2=meta1-ent1

SELECT resumen
replace meta WITH meta1
replace ent WITH ent1
replace est WITH est1
replace tot WITH x1
replace resta WITH x2

skip
ENDDO
WAIT WINDOW TIMEOUT 0.8 "Terminó con exito la Automatización de Datos"
SET FILTER TO
CLOSE DATABASES
CLEAR ALL




Carlos Miguel FARIAS

unread,
Sep 22, 2014, 11:10:03 AM9/22/14
to Grupo Fox
Saul. Aclarame.
Abres Lista1 in 0 (o sea la primera libre), haces select de Lista (cual es?)
Estableces un filtro y haces un GO TOP, pero no hay certeza de que a que tabla
Referencias una tabla ben pero no indicas donde lo abres o que.
El skip es sobre resumen (?).
Los count recorren toda la lista
Es confuso difuso entre programadores lelos ;-D
Trato de ayudar, con onda, porque para Honda, no me alcanza!!!
Saludos: Miguel, La Pampa (RA)

Saúl Piña

unread,
Sep 22, 2014, 11:26:00 AM9/22/14
to publice...@googlegroups.com
Tienez razon, va de nuevo el codigo:  (tomé un backup por error) el count siempre me ha funcionado....no se si deba cambiar eso.


SET EXACT ON

*OPEN DATABASE bd.dbc
USE Lista1 IN 0 shared
select lista

SET FILTER TO NOT EMPTY(IMPAGO)
GO TOP

USE resumen IN 0 shared


DO WHILE !EOF()
SELECT lista
COUNT FOR lista.letra==resumen.letra AND lista.seccion=resumen.seccion TO meta1
COUNT FOR lista.letra==resumen.letra AND lista.seccion=resumen.seccion AND estatus=1 TO ent1
COUNT FOR lista.letra==resumen.letra AND lista.seccion=resumen.seccion AND estatus>1 TO est1

x1=ent1+est1
x2=meta1-ent1

SELECT resumen
replace meta WITH meta1
replace ent WITH ent1
replace est WITH est1
replace tot WITH x1
replace resta WITH x2

select lista

Antonio Meza

unread,
Sep 22, 2014, 2:23:57 PM9/22/14
to publice...@googlegroups.com
Hola Saul !!

El código que envías nuevamente tiene problemas, por ejemplo tienes estas tres lineas
USE resumen IN 0 shared
DO WHILE !EOF()
SELECT lista

Lo que se entiende es que el !EOF() se esta aplicando a la tabla RESUMEN, y luego hasta abajo tienes
select lista
skip 
ENDDO

Lo que se entiende que la tabla LISTA le estas avanzando un registro y luego el DO WHILE va a comparar si estas al final con el !EOF() de la tabla LISTA, cuando se entiende que debería ser RESUMEN, por lo que tu ciclo esta mal diseñado, ya que primero valida para resumen y luego valida para lista.

Cambiando de tema y contestando a tu pregunta, para el caso de MYSQ e incluso para cualquier motor de base de datos, lo que tu traes son cursores en memoria, y los traes o puedes traer con los datos que tu necesites, es decir aplicando filtro en el SELECT con el WHERE, entonces remplazando las lineas siguientes
select lista
SET FILTER TO NOT EMPTY(IMPAGO)
GO TOP 

Tendrías que enviar un SQLEXEC con un SELECT * from Lista where len(impago) >= 1, por darte la idea no se si realmente LEN funcione dentro de SQL, así que tendrías que buscar alguna función para saber si el campo esta vació, lo que quiero que entiendas es la diferencia. Con eso ya tendrás un cursor con los datos que necesitas.

La otra opciones es que puedes traerte todos los datos de la tabla con Select * from LISTA y luego simplemente aplicar el filtro como lo tienes con SET FILTER como lo haces con una tabla DBF, lo recomendado en el caso de un servidor de base de datos es traer siempre los datos que vas a ocupar para que las consultas sean menos pesadas, en un red local no vas a notar diferencia pero por Internet si.

Si te funciona el COUNT lo puedes seguir usando, pero recuerda que debes traer el cursor del servidor de base de datos con tu SELECT ya sea con filtro o sin filtro, como te comentaba arriba puedes solicitar un select que te devuelva el valor sumando o puedes pedir que te mande todos los datos de la tabla y aplicar el count como lo tienes en 3 lineas, en mi caso armaría 3 select que me cuente lo que necesito y me devuelvan 3 cursores con el valor de cada uno. pero ya es cuestión de gustos y disgustos jajaj ejemplo:

select * from lista where lista.letra==?resumen.letra AND lista.seccion=?resumen.seccion
o
select cnt(valor) where lista.letra==?resumen.letra AND lista.seccion=?resumen.seccion ..... .etc..

a diferencia de

COUNT FOR lista.letra==resumen.letra AND lista.seccion=resumen.seccion TO meta1


saludos
Antonio Meza

Saúl Piña

unread,
Sep 22, 2014, 2:36:16 PM9/22/14
to publice...@googlegroups.com
Gracias por los comentarios, la rutina que expuse es un ejemplo de como le doy un barrido a las tablas (recorriendo cada fila) y reemplazar segun lo encontrado. 
replanteo mi pregunta:  puedo hacer esto mismo con la opcion consulta de HeidiSQL ? 

Sin tener que usar vfp, sino que directamente del administrador de HeidiSQL o Navicat, puedo hacer este tipo de rutinas?  existe Do while o Scan para mariadb o MySQL?

gracias

Mauricio Gonzalez

unread,
Sep 22, 2014, 2:36:21 PM9/22/14
to publice...@googlegroups.com
SET EXACT ON
*
USE Lista1 IN 0
USE resumen IN 0
SET FILTER TO !EMPTY(IMPAGO)
GO TOP 
*
USE resumen IN 0
*
SCAN
.......SELECT lista1
.......SUM FOR ben.letra == resumen.letra AND ben.seccion=resumen.seccion TO meta1
.......SUM FOR ben.letra == resumen.letra AND ben.seccion=resumen.seccion AND estatus = 1 TO ent1 .......SUM FOR ben.letra==resumen.letra AND ben.seccion=resumen.seccion AND estatus > 1 TO est1
.......x1=ent1+est1
.......x2=meta1-ent1
*
.......SELECT resumen
.......replace meta WITH meta1, ent WITH ent1, est WITH est1, tot WITH x1, resta WITH x2
ENDSCAN
*

Saúl Piña

unread,
Sep 22, 2014, 2:45:35 PM9/22/14
to publice...@googlegroups.com
Gracias de nuevo, pero el punto es: se puede hacer esto con el propio administrador de MySQL o mariadb? el SCAN lo puedo usal en las consultas directas de MySQL o mariadb?

Lo que quiero es hacer lo mismo (de vfp) pero ahora en el administrador HeidiSQL o Navicat.



gracias.


Jose Mario

unread,
Sep 22, 2014, 3:24:20 PM9/22/14
to publice...@googlegroups.com
no es burla pero estamos iguales en el aprendizaje
de dbms, nunca habia visto esas instruciones dentro de bucle

COUNT FOR lista.letra==resumen.letra AND lista.seccion=resumen.seccion TO meta1
COUNT FOR lista.letra==resumen.letra AND lista.seccion=resumen.seccion AND estatus=1 TO ent1
COUNT FOR lista.letra==resumen.letra AND lista.seccion=resumen.seccion AND estatus>1 TO est1
 
si lo colocas dentro de un bucle, el count lo estaria haciendo
por cada registro que leyera de ese archivo

USE resumen IN 0 shared
DO WHILE !EOF()
SELECT lista

no se porque abrís 
use resumen in 0 shared
y luego despues del
do while abris
lista

Saúl Piña

unread,
Sep 22, 2014, 4:03:30 PM9/22/14
to publice...@googlegroups.com
Mario "USE" es igual a realmente tener acceso a la tabla.

"SELECT" es igual a seleccionar la tabla para trabajar en ella. 

Asi lo he entendido yo. 


Pero por favor, ya dejen el ejemplo. (es solo para simular lo que quiero llegar a realizar en algun administrador). 

POR FAVOR YA OLVIDENSE DEL EJEMPLO (si está bien o no) y mejor diganme si puedo hacer este tipo de rutinas en un administrador ya sea HeidiSQL o Navicat

gracias.

Edgar Acevedo

unread,
Sep 22, 2014, 4:17:05 PM9/22/14
to publicesvfoxpro
NO se hacer en MySQL lo que solicitas, pero alguien me dijo una vez que para eso existían las "Vistas" en VFP:  Para que una vez hayas conectado con una base de datos en MySQL, gracias a las "vistas", las podás tratar como si fueran tablas de VFP.  Específicamente creo que le llaman "vistas remotas".  Pero jamás las he usado.  Sería de probar.  

Saludos,


Edgar Acevedo.

Antonio Meza

unread,
Sep 22, 2014, 4:53:50 PM9/22/14
to publice...@googlegroups.com
Saul, si se puede y se llaman Store Procedure solo que al principio aprender el lenguaje para diseñarlos no es sencillo.

Y la otra opcion es tratar de ejecutar los SELECT directamente en HeidiSql o navicat eso si lo puedes hacer pero solo los select, usar scan y do while seria usar store procedire.

saludos
Antonio Meza

Víctor Hugo Espínola Domínguez

unread,
Sep 22, 2014, 5:02:54 PM9/22/14
to publice...@googlegroups.com
Hola Saúl

Aunque se pudiera no lo deberías hacer!

Solamente un cursor creado con una consulta puede ser recorrido fila por fila, pero es considerado una mala práctica por los gurús del lenguaje SQL.

http://www.sqlservercentral.com

"RBAR is pronounced "ree-bar" and is a "Modenism" for "Row-By-Agonizing-Row".

First step towards the paradigm shift of writing Set Based code:
Stop thinking about what you want to do to a row... think, instead, of what you want to do to a column."

(play on words) "Just because you CAN do something in T-SQL, doesn't mean you SHOULDN'T."


--Jeff Moden

Saludos,
Víctor.
Lambaré - Paraguay.





Guillermo MDQ

unread,
Sep 22, 2014, 5:46:03 PM9/22/14
to publice...@googlegroups.com
Saul, lo que vos necesitas lo podes con la funcion COUNT de MySQL dentro de un Select.
Consulta la ayuda de MySQL o MariaDB y la podras usar sin problemas dentro del Heidi o Navicat.

Saludos
Guillermo

Guillermo MDQ

unread,
Sep 22, 2014, 5:50:48 PM9/22/14
to publice...@googlegroups.com
Saul, lo que vos necesitas lo podes hacer con la funcion COUNT de MySQL dentro de un Select.

Consulta la ayuda de MySQL o MariaDB y la podras usar sin problemas dentro del Heidi o Navicat.

Saludos
Guillermo


El lunes, 22 de septiembre de 2014 18:02:54 UTC-3, Víctor Hugo escribió:

Saúl Piña

unread,
Sep 22, 2014, 7:43:57 PM9/22/14
to publice...@googlegroups.com
Perfecto, gracias, es lo que queria saber, si se puede realizar y donde y que tema hay que investigar. 

Muy agradecido...

Carlos Miguel FARIAS

unread,
Sep 23, 2014, 6:04:23 AM9/23/14
to Grupo Fox

Recomiendo el libro Groff para aprender sql. Las practicas se pueden hacer en el mismo vfp con dbfs.
Saludos: Miguel, La Pampa ( RA)

Carlos Miguel FARIAS

unread,
Sep 23, 2014, 7:56:53 PM9/23/14
to Grupo Fox
En SQL, la función sumaria COUNT(*) cuenta cantidad de registros existentes totales en el grupo.
Pero se pueden contar registros que cumplan ciertas condiciones
COUNT(IIF(Importe>1000,1,0)) estaría contando registros que en el grupo tengan un importe mayor que 1000
En mysql pondrás IF en lugar IIF y en otros SGBD tendrás que usar CASE WHEN u otras equivalentes
Cuando usamos agrupamiento (GROUP BY) hay que recordar que todos los campos no "envueltos" en una función sumaria (COUNT, SUM, AVG, etc.) que se listan en el SELECT, deben aparecer en el GROUP BY, aunque en esté pueden aparecer algunos campos que no se muestren.
COUNT(columna) cuenta cuantos registros en el grupo tienen columna con valor distinto de NULL
COUNT(DISTINCT columna) cuenta cuantos registros del grupo tienen valores distintos (o mejor dicho cuantos valores distintos de columna hay en el grupo)
Por ejemplo:
SELECT F.Fecha, COUNT(DISTINTC F.idFactura) as "CantFacturas",;
    COUNT(DISTINCT D.idProducto) as "ProductosDistintos";
 FROM Facturas F INNER JOIN Detalle D ON (F.idFactura = D.IdFactura);
 GROUP BY F,Fecha;
 ORDER BY 1
Tira por fechas, cuantas facturas se hicieron y cuantos productos diferentes se vendieron.

El libro recomendado para SQL (que te permite todo el dbase de acceso a datos) es:
Guia de SQL de James GROFF y Paul WEINBERG
Buen Provecho!!!
Saludos: Miguel, La Pampa (RA)

Saúl Piña

unread,
Sep 23, 2014, 8:31:18 PM9/23/14
to publice...@googlegroups.com
gracias  a todos, ya lo logré a mi manera pero lo hice.

El autor es de alguien que no conozco ya que el codigo lo vi en la web y me sirvió mucho. 

se trata de pasar los datos de un cursor a una tabla de mysql


Reply all
Reply to author
Forward
0 new messages