Page 1 of 2

Cómo Insertar registros a na tabla?

Posted: Sun Jan 26, 2025 5:56 pm
by Armando
Amigos del foro:

Hoy les pido ayuda y escuchar sus sabios consejos para, teniendo una tabla con n cantidad de registros, cómo insertar
n cantidad de registros en cierta posición?, me explico con un ejemplo, si tengo la tabla con estos registros, con dos campo
para no complicar las cosas, el número que antecede al nombre de las frutas es de un campo auto incrementable.

1 Manzana
2 Pera
3 Naranja
4 Mandarina

Si quiero insertar Lima entre Pera y Naranja para quedar así
1 Manzana
2 Pera
3 Lima
4 Naranja
5 Mandarina

Tengo la idea de cómo hacerlo pero me gustaría escuchar sus soluciones para no "inventar el agua caliente",
con el pseudocódigo sería suficiente.

Saludos cordiales a todos

Re: Cómo Insertar registros a na tabla?

Posted: Mon Jan 27, 2025 6:05 pm
by Armando
Amigos:

Lo he resuelto pasando los registros a una nueva tabla temporal, pero me gustaría saber
si alguien lo haya hecho de otra forma. muestro aquí cómo lo hice por si a alguien mas le sirve.

1.- Estando el foco en el browse, el usuario oprime la tecla INS
2.- En un dialogo solicito el número de renglones o registros a insertar
3.- Identifico el número de registros donde el usuario dio el clic, recuerden que tengo una columna auto incrementable
4.- Con un DO WHILE paso los registros a la tabla temporal, si el número de registro a copiar es mayor que el numero de registro donde el usuario dio clic, entro en un FOR NEXT para agregar, a la tabla temporal, el número de registros que el usuario quiere insertar, al terminar el FOR NEXT sigo pasando los registros faltantes hasta llegar al final de la tabla
5.- Por último, limpio la tabla original y copio todos los registros de la tabla temporal y refresco el browse

Saludos

Re: Cómo Insertar registros a na tabla?

Posted: Mon Jan 27, 2025 10:30 pm
by FiveWiDi
No sé si se puede insertar un registro de la misma manera que se hace con una array.

Yo lo haría usando un índice y un campo "DUMMYREC"

1º Veo la DBF en Xbrowse con el índice sobre campo DUMMYREC
2º Estoy en el registro 89.
3º Voy a insertar 4 registros
4º Voy al 'último' registro.
5º Hago
While Recno() <> 89
DUMMYREC := DUMMYREC + 4 con
Skip(-1)
End
nMyDUMMYREC := DUMMYREC - 4
6º Hago esto 4 veces
Append()
DUMMYREC := nMyDUMMYREC++
7º Aplico el índice sobre el campo DUMMYREC

Creo que funcionaría.

Si mientras trabaja el sistema se cae, reindexando no se pierde nada.

Re: Cómo Insertar registros a na tabla?

Posted: Mon Jan 27, 2025 11:48 pm
by Armando
Amigo Carlos:

Es parecido a lo que hago, una diferencia es que yo utilizo tablas MySql con ADO.

Gracias por la idea.

Saludos

Re: Cómo Insertar registros a na tabla?

Posted: Tue Jan 28, 2025 3:41 pm
by sysctrl2
hacer eso en una tabla de 1 millon de reregistros OPS :o :shock:

Re: Cómo Insertar registros a na tabla?

Posted: Tue Jan 28, 2025 4:57 pm
by FiveWiDi
Armando wrote: Mon Jan 27, 2025 11:48 pm Amigo Carlos:

Es parecido a lo que hago, una diferencia es que yo utilizo tablas MySql con ADO.

Gracias por la idea.

Saludos
Entonces con más motivo.

Si no voy equivocado, en DBF se añaden al final del fichero, en MySql es el propio motor que decide donde grabarlo, por tanto yo usaría un índice para lo que mencionas.

Y tal como dice César, con 1 millón de registros...

Re: Cómo Insertar registros a na tabla?

Posted: Tue Jan 28, 2025 7:37 pm
by Armando
Paisano, y amigos:

Afortunadamente el browse puede llegar tener hasta 50 registros.

Saludos

Re: Cómo Insertar registros a na tabla?

Posted: Wed Jan 29, 2025 11:34 am
by jbrita
Hola Armando.. yo lo hago de otra forma, tengo un contador que va de 3 o 5 en 5 y cuando estoy en browse le sumo +1 al contador actual
eso asi de facil

saludos

Re: Cómo Insertar registros a na tabla?

Posted: Wed Jan 29, 2025 4:24 pm
by Armando
Hola José:

Es otra alternativa, muchas gracias

Saludos al crio

Re: Cómo Insertar registros a na tabla?

Posted: Thu Jan 30, 2025 11:24 am
by cmsoft
Armando, buenos dias.
Te consulto: porque cambiar el campo auto incremental? Si es para mostrar en forma ordenada, Mysql te lo permite con la clausula ORDER BY.
Y el Xbrowse lo respeta perfectamente.

Code: Select all | Expand

#INCLUDE "fivewin.ch"
#INCLUDE "tdolphin.ch"
FUNCTION Armando()
LOCAL oBrw, oCn, oRs, oForm, oBtn
   CONNECT oCn HOST 'localhost' ;
                    USER 'root' ;
                    PASSWORD 'secret' ;
                    PORT 3306 ;
                    FLAGS 0;
                    DATABASE 'test'
   if oCn == nil
      ? "can not connect to server"
      return nil
   endif
   //Creo una tabla temporal
   oCn:Execute("";
    + "CREATE TEMPORARY TABLE IF NOT EXISTS armando ";
    +"( `id` INT(10) NOT NULL AUTO_INCREMENT, ";    
    +"`nombre` VARCHAR(50) NOT NULL,";    
    +"`orden` INT(10) NOT NULL,";
    +"PRIMARY KEY (`id`)) ENGINE=INNODB DEFAULT CHARSET=utf8")
   //Inserto lo basico 
   oCn:Execute("INSERT INTO armando (orden,nombre) VALUES (1,'Manzana'),(2, 'Pera'),(3, 'Naranja'),(4, 'Mandarina')")
   oRs   := oCn:query("SELECT * FROM armando ORDER BY orden ")
   DEFINE DIALOG oForm TITLE "Armando" FROM 05,15 TO 36,99    
   @05,05 XBROWSE oBrw DATASOURCE oRs;
              COLUMNS "orden","nombre";
              HEADERS "Orden","Nombre";
              SIZES 80,200;
              OF oForm CELL SIZE 200,200 PIXEL       
   oBrw:CreateFromCode()
   @ 05,220 BUTTON oBtn PROMPT "Insertar" SIZE 30,10 OF oForm PIXEL ACTION Insertar(oRs,oCn,oBrw)
   ACTIVATE DIALOG oForm CENTER 
RETURN nil


STATIC FUNCTION Insertar(oRs,oCn,oBrw)
LOCAL oDlg1, nOrden := 0, cNombre := SPACE(50), oGet := ARRAY(2), oBtn := ARRAY(2), lRta := .f.
    DEFINE DIALOG oDlg1 TITLE "Insertar Registro" FROM 03,20 TO 14,60 
       
       @ 07, 05 SAY "Nombre:" OF oDlg1 PIXEL RIGHT SIZE 40,10
       @ 22, 05 SAY "Orden:"  OF oDlg1 PIXEL RIGHT SIZE 40,10       
       @ 05, 50 GET      oGet[1] VAR cNombre  OF oDlg1 PIXEL
       @ 20, 50 GET      oGet[2] VAR nOrden PICTURE "9999" OF oDlg1 PIXEL RIGHT       
       
       @ 35,30 BUTTON oBtn[1] PROMPT "&Grabar" OF oDlg1 SIZE 30,10 ;
               ACTION ((lRta := .t.), oDlg1:End() ) PIXEL
       @ 35,80 BUTTON oBtn[2] PROMPT "&Cancelar" OF oDlg1 SIZE 30,10 ;
               ACTION ((lRta := .f.), oDlg1:End() ) PIXEL
    ACTIVATE DIALOG oDlg1 CENTER 
IF !lRta .or. nOrden <=0   
   RETURN nil 
ENDIF 
oCn:Execute("UPDATE armando SET orden = orden + 1 WHERE orden >= "+str(nOrden))
oCn:Execute("INSERT INTO armando (nombre,orden) VALUES ('"+cNombre+"',"+STR(nOrden)+")")  
oRs:Refresh()
oBrw:Refresh(.t.)

RETURN nil
Es otra idea

Re: Cómo Insertar registros a na tabla?

Posted: Thu Jan 30, 2025 5:11 pm
by sysctrl2
Interesante tocayo,
hay que probar :shock:

Re: Cómo Insertar registros a na tabla?

Posted: Fri Jan 31, 2025 1:00 am
by Armando
César:

Aportando, como siempre, en mi caso, acepto que en mi primer post no lo puse, pueden existir registros en blanco
el usuario los necesita como separadores, entonces el campo auto incremental es obligado.

Además, en ocasiones el usuario puede cambiar el orden dando clic en el encabezado del browse, si fuera el caso,
después ya no podría volver al órrden de captura y todos los registros en blanco quedarían al principio del browse

Muchas gracias por tu tiempo y ejemplo.

Saludos

Re: Cómo Insertar registros a na tabla?

Posted: Fri Jan 31, 2025 10:17 am
by cmsoft
Armando, en el ejemplo que te pasé, hay un campo autoincremental que lo va a manejar la base de datos, que va a ser el orden natural que el usuario vaya ingresando los datos, luego el campo orden que va a ser unico para que el usuario pueda darle un orden, y un campo nombre (por el cual tambien se puede ordernar si quieres en xbrowse agregando la clausula AUTOSORT) por si lo quiere ordenarlo por ese campo.
Seguramente no estoy comprendiendo bien tu necesidad final, pero Fivewin y Mysql pueden darte la solucion que necesitas.

Re: Cómo Insertar registros a na tabla?

Posted: Sat Feb 01, 2025 12:41 am
by Armando
César:

Muchas gracias, así es como lo resolví.

Saludos

Re: Cómo Insertar registros a na tabla?

Posted: Mon Feb 03, 2025 10:01 pm
by nageswaragunupudi
Another way, using only Auto-increment field.

Code: Select all | Expand

#include "fivewin.ch"

//----------------------------------------------------------------------------//

function Main()

   local oCn, oRs

   oCn   := Fw_OpenAdoConnection( "MYSQL,209.250.245.152,fwh,fwhuser,FiveTech@2022", .t. )
   oRs   := CreateTableFruits( oCn )

   // Right-click to insert a new fruit
   XBROWSER oRs TITLE "FRUITS" SETUP ( ;
      oBrw:bRClicked := { |r,c,f,o| InsertFruit( oRs ), o:Refresh() } )

   oRs:Close()
   oCn:Close()

return nil

//----------------------------------------------------------------------------//

function CreateTableFruits( oCn )

   local oRs, v

   oCn:Execute( "DROP TABLE IF EXISTS fruits" )
   FWAdoCreateTable( "fruits", { { "fruit", "C", 15, 0 } }, oCn )

   oRs   := FW_OpenRecordSet( oCn, "fruits" )
   oRs:Sort := "id"
   for each v in { "Manzana", "Pera", "Naranja", "Mandarina", "Mango", "Banana", "Papaya", "Grape" }
      oRs:AddNew( "fruit", v )
   next

return oRs

//----------------------------------------------------------------------------//

function InsertFruit( oRs )

   local nSave := oRs:AbsolutePosition
   local nId   := oRs:Fields( "id" ):Value
   local cSql

   PRIVATE cId   := LTrim( Str( nId ) )
   PRIVATE cFruit   := PadR( "Lima", 15 )

   if !MsgGet( "Fruit Name:", "At Line : " + cId, @cFruit ) .or. Empty( cFruit )
      return nil
   endif
   cFruit   := Trim( cFruit )

   CursorWait()

TEXT INTO cSql
UPDATE fruits LEFT JOIN fruits a ON fruits.id = a.id + 1
 SET fruits.fruit = a.fruit
 WHERE fruits.id > &cId
ENDTEXT

   WITH OBJECT oRs:ActiveConnection
      :Execute( "INSERT INTO fruits ( fruit ) VALUES ( '' )" )
      :Execute( cSql )
      :Execute( "UPDATE fruits SET fruit = '&cFruit' WHERE id = &cId" )
   END
   oRs:Requery()
   oRs:AbsolutePosition := nSave
   CursorArrow()

return nil

//----------------------------------------------------------------------------//
Image