FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour FWMYSQL
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
FWMYSQL
Posted: Thu Sep 08, 2016 04:19 PM
Estimados:
Cual sería la data o el motodo que, de una tabla con un campo autoincremental, me permita saber cual es el valor que corresponde a un nuevo registro.
Si bien cuando hago un :Append() y luego :Save() me guarda correctamente el valor, desearía mostrarlo antes en la captura de datos en el formulario.
Otra consulta:
Cual sería el proceso correcto despues de un :Append() para que el Browse refleje la realidad del orden de la tabla.
Hice esta prueba. En una tabla ordenada por nombre, agrego un registro que quede por orden alfabetico entre dos registros, y cuando refresca el browse el orden resultante no refleja el orden real. Si cierro la Query y la vuelvo a abrir, ahi si muestra los datos correctamente.
El ejemplo sería este:
Code (fw): Select all Collapse
STATIC FUNCTION ArmarBrowse(oWnd)
    nFilter := 1
    nSeekWild := 1
    oQryBrw := oApp:oServer:Query("SELECT * FROM agenda WHERE usuario = "+;
               ClipValue2Sql(oApp:usuario)+ " ORDER BY nombre ")
     DEFINE WINDOW oDlgBrw FROM 0,0 TO oApp:oWnd:nWidth-200, oApp:oWnd:nHeight - 300;
        NOSYSMENU NOCAPTION NOMINIMIZE NOMAXIMIZE  OF oWnd 
     @ 05,01 XBROWSE oBrw DATASOURCE oQryBrw SIZE oApp:oWnd:nWidth-200, oApp:oWnd:nHeight - 300;
       OF oDlgBrw AUTOSORT ;
       COLUMNS "id","nombre","direccion","Telefono","celular","mail","empresa";
       HEADERS "Id","Apellido y Nombre","Direccion","Tel.Fijo","Tel.Celular","Email","Empresa";
       SIZES 35,250,95,80,80,200,200;
       ON DBLCLICK (Formu(.f.),oBrw:Refresh())
     @ 00,00 SAY oBrw:oSeek PROMPT "Buscar:"  OF oDlgBrw 
     @ 00,10 SAY oBrw:oSeek PROMPT ""  SIZE 500,20 OF oDlgBrw 
     @ 02,10 COMBOBOX nFilter SIZE 200,60 OF oDlgBrw ;
         ITEMS { "Buscar por...", "Filtrar por..." } ;
         ON CHANGE ( oBrw:Seek( "" ), oBrw:lIncrFilter := nFilter > 1,  oBrw:SetFocus() )

     @ 02,72 COMBOBOX nSeekWild SIZE 200, 60 OF oDlgBrw ;
         ITEMS { "Que comience con..", "Que contenga" } ;
         ON CHANGE ( oBrw:lSeekWild := ( nSeekWild > 1 ), oBrw:Seek( "" ), oBrw:SetFocus() )

     oBrw:nFreeze := 7
     oBrw:CreateFromCode()
     ACTIVATE WINDOW oDlgBrw  ON INIT oDlgBrw:Move(0,0)
     oQryBrw:GoTop()
RETURN nil

***************************************
** Formulario de altas y modificaciones
STATIC FUNCTION Formu (lAlta)
LOCAL oGet := ARRAY(7), oBot := ARRAY(2), oForm, lRta := .f., aCor,  oFont, oError
IF lAlta
   oQryBrw:Append()
   oQryBrw:usuario := oApp:usuario
ENDIF
DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-11.5
DO WHILE .T.

DEFINE DIALOG oForm TITLE IF(lAlta,"Alta","Modificacion") + " de Contacto" FROM 05,15 TO 25,80 FONT oFont
   acor := AcepCanc(oForm)
   @ 07, 05 SAY "Id:"                OF oForm PIXEL SIZE 60,20 RIGHT
   @ 22, 05 SAY "Apellido y Nombre:" OF oForm PIXEL SIZE 60,20 RIGHT
   @ 37, 05 SAY "Direccion:"         OF oForm PIXEL SIZE 60,16 RIGHT
   @ 52, 05 SAY "Telefono:"          OF oForm PIXEL SIZE 60,16 RIGHT
   @ 67, 05 SAY "Celular:"           OF oForm PIXEL SIZE 60,16 RIGHT
   @ 82, 05 SAY "Mail:"              OF oForm PIXEL SIZE 60,16 RIGHT
   @ 97, 05 SAY "Empresa:"           OF oForm PIXEL SIZE 60,16 RIGHT
 
   @ 05, 70 GET oGet[1] VAR oQryBrw:id        OF oForm PICTURE "9999999" PIXEL RIGHT WHEN(.F.)
   @ 20, 70 GET oGet[2] VAR oQryBrw:nombre    OF oForm PIXEL CUEBANNER "Nombre contacto"
   @ 35, 70 GET oGet[3] VAR oQryBrw:direccion OF oForm PIXEL CUEBANNER "Domiclio contacto"
   @ 50, 70 GET oGet[4] VAR oQryBrw:telefono  OF oForm PIXEL CUEBANNER "Telefono fijo contacto"
   @ 65, 70 GET oGet[5] VAR oQryBrw:celular   OF oForm PIXEL CUEBANNER "Telefono movil contacto"
   @ 80, 70 GET oGet[6] VAR oQryBrw:mail      OF oForm PIXEL CUEBANNER "Direccion de correo electronico"
   @ 95, 70 GET oGet[7] VAR oQryBrw:empresa   OF oForm PIXEL CUEBANNER "Empresa para la que trabaja"
 
   @ acor[1],acor[2] BUTTON oBot[1] PROMPT "&Grabar" OF oForm SIZE 30,10 ;
           ACTION ((lRta := .t.), oForm:End() ) PIXEL
   @ acor[3],acor[4] BUTTON oBot[2] PROMPT "&Cancelar" OF oForm SIZE 30,10 ;
           ACTION ((lRta := .f.), oForm:End() ) PIXEL CANCEL
ACTIVATE DIALOG oForm CENTER 
IF !lRta
   RELEASE oFont
   oQryBrw:Cancel()
   RETURN nil
ENDIF
TRY
  oApp:oServer:BeginTransaction()
  oQryBrw:Save()
  *oQryBrw:Refresh() // Probe con esto solo y sin esto
  *oBrw:Refresh()     // Probe con esto y sin esto
  oApp:oServer:CommitTransaction()
CATCH oError
    ValidaError(oError, oQryBrw)
  LOOP
END TRY
EXIT
ENDDO
RELEASE oFont
RETURN nil

La funcion se llama de la ventana contenedora
Gracias
Posts: 582
Joined: Fri Oct 07, 2005 02:17 PM
Re: FWMYSQL
Posted: Thu Sep 08, 2016 06:25 PM

Saludos

No se si es lo que preguntas exactamente, pero lo que Yo uso para saber que numero corresponde en un autoincremental es la función MAX de MySQL, me da el ultimo valor en la tabla y obviamente el nuevo seria ese mas 1

"Select max(nombre_campo_autoincremental) from "+nombre_tabla

Enrrique Vertiz Pitta

Lima-Peru

xHb 1.23.1026X, Fwh 25.01, BCC74, MySQL 8.0.X, SQLLIB 1.9m
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: FWMYSQL
Posted: Thu Sep 08, 2016 08:22 PM

cmsoft:

Para la primera pregunta, tal vez con LAST_INSERT_ID()

Para la segunda pregunta, con oQryBrw:Requery()

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 682
Joined: Tue Feb 14, 2006 09:48 AM
Re: FWMYSQL
Posted: Fri Sep 09, 2016 08:14 AM
Como te comenta Armando, para lo primero
Code (fw): Select all Collapse
SELECT last_insert_id() //último autoincremental creado, no le indicamos tabla, es el <strong>último creado</strong>
o
SELECT auto_increment FROM information_schema.tables WHERE table_schema='BaseDeDatos' AND table_name='Tabla'

Paradojicamente el metodo que propone Enrique parece que deberia ser el más ineficiente porque obliga a leer toda la tabla, pero el motor de la base de datos lo optimiza y recurre al esquema en lugar de hacer el calculo de Max sobre todos los registros, con lo cual es valido e igual de rápido.

En cualquier caso last_insert_id() parace lo más adecuado.

Con referencia a la actualización de registros, no conozco los metodos de FwMySQL, pero debes refrescar el origen de datos, y despues el Browse, ambas dos cosas.
Yo probaria así
Code (fw): Select all Collapse
   oQryBrw:Save()
   oQryBrw:Refresh() 
   oBrw:Refresh()
Saludos desde Mallorca
Biel Maimó
http://bielsys.blogspot.com/
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Re: FWMYSQL
Posted: Fri Sep 09, 2016 11:16 AM

Gracias a todos por responder!
Con respecto a la primer pregunta, lo hacia para ver el comparativo con Dolphin que tine la funcion :GetAutoIncrement("table") que es muy util para estos casos. Me referia a si la clase la traia, para no hacer funciones propias ni motodos extendidos. En realidad, la el metodo de Dolphin hace exactamente lo que indica Biel como segunda opcion.
LAST_INSERT_ID() me devuelve 0 a menos que haya hecho un INSERT previamente y siempre y cuando le haya indicado que el campo autoincremental lo calcule la base de datos.
Esto
INSERT INTO marcas (nombre) VALUES ("MARCA 2");
INSERT INTO marcas (codigo,nombre) VALUES (3,"MARCA 3");
SELECT LAST_INSERT_ID()
con codigo como campo autoincremental me devuelve 2.
Lo que propone Enrique, si como dice Biel es rapido sería una buena opcion... O la segunda opcion de Biel que es lo que hace Dolphin

Con respecto a la segunda pregunta, consulto:
Armando: oQryBrw:Requery() vuelve a hacer la consulta a la base? Pregunto porque en una tabla grande, puede ser lento que cada vez que tengo que refrescar, haga toda la consulta de nuevo.
Biel:
oQryBrw:Save()
oQryBrw:Refresh()
oBrw:Refresh()
es lo que hago, pero la respuesta que obtengo esta desordenada, no respeta el orden alfabetico que deberia tener.
Muchas gracias a los tres por responder.

Posts: 1380
Joined: Fri Oct 14, 2005 01:28 PM
Re: FWMYSQL
Posted: Fri Sep 09, 2016 02:06 PM
CM;
Uso TDolphin y esto es lo que hago. Teniendo la ventana de un xBrowse, abro un dialog y luego de guardar procedo asi:
Code (fw): Select all Collapse
                     ::GuardaA( oData, lAgrega ), ;
                     ::oQryA:GoTo( ::oQryA:Seek( if( ::oQryA:cOrder == "dnia",  oData:dniA , ;    // :cOrder toma el string de COLUMNS (xbrowse)
                                                 if( ::oQryA:cOrder == "Alumno", oData:alumno, )), ;
                                                 ::oQryA:cOrder,,,, .f. ) ), ;
                     oDlg:End(), ;
                     if( !Empty( oBrw ), ( oBrw:Refresh(), oBrw:SetFocus ), ) )

Luego de Guardar hago un :GoTo(), respuesta de un :Seek, ya que este me devuelve el "recno".
En este caso pregunto si el orden vigente es por DNI, para que busque por ese campo, caso contrario busca por descripcion (en este caso apellido/ y nombres/)
Luego, refresco el browse

Como verás... no estudié todos las opcione de TDolphin :-) , pero tengo el resultado esperado
Resistencia - "Ciudad de las Esculturas"

Chaco - Argentina
Posts: 1380
Joined: Fri Oct 14, 2005 01:28 PM
Re: FWMYSQL
Posted: Fri Sep 09, 2016 02:12 PM
Agrego;
En Guardar hago:
Code (fw): Select all Collapse
   if lAgrega
      ...
      oData:oServer:Insert( "alumnos", ::aCamposA, aInsert )
   else
      ...
      cWhere:= " WHERE id_alumno="+StrZero( oData:id_alumno,7 )
      cQry += cWhere
      oData:oServer:SqlQuery( cQry )
   end
   oData:LoadQuery()
Resistencia - "Ciudad de las Esculturas"

Chaco - Argentina
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: FWMYSQL
Posted: Fri Sep 09, 2016 03:31 PM

cmsoft:

Tal vez la diferencia es que yo estoy hablando de ADO puro y tú utilizas TDolphin,
en ADO puro el campo autoincremental es autoincremantal, no he visto que haya
posibilidad de que tú lo autoincrementes.

De igual manera la segunda pregunta, hablo de ADO puro y he leído que el REQUERY
solo lee los registros nuevos o que han sufrido cambios.

Saluos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Re: FWMYSQL
Posted: Fri Sep 09, 2016 03:49 PM

Gracias a ambos por la respuesta:
Estoy queriendo comenzar a utilizar la nueva clase nativa de FW, por eso son las preguntas.
Son correctas las apreciaciones de ambos.
Mi duda era sobre la clase FWMYSQL, por si alguno ya la había utilizado

Continue the discussion