obtener el ultimo id registrado

2,453 views
Skip to first unread message

Saúl Piña

unread,
Mar 2, 2015, 4:49:39 PM3/2/15
to publice...@googlegroups.com
Saludos, tengo un campo de tipo incremental y lo que deseo es saber cuando cual es el num id incremental registrado, es decir, al momento de guardar un nuevo registro con insert into en una tabla mysql, en la tabla se genera un id por el registro insertado previamente, mi pregunta es como puedo saber cual es ese ID.

Sabiendo que el programa trabaja en red con 15 equipos guardando datos al mismo tiempo..

gracias.

Antonio.xt

unread,
Mar 2, 2015, 5:11:10 PM3/2/15
to publice...@googlegroups.com

Para obtener el ultimo id insertado en MS SQL yo uso esta sentencia:

SELECT @@IDENTITY as [MiUltimo_Id]

En MySQL, creo que es:

SELECT LAST_INSERT_ID();

ZeRoberto

unread,
Mar 2, 2015, 5:12:51 PM3/2/15
to publicesvfoxpro
SELECT CampoID FROM tabla ORDER BY CampoID DESC LIMIT 1


Eric Natareno Guerra

unread,
Mar 2, 2015, 5:13:59 PM3/2/15
to publicesvfoxpro

Disculpa Antonio, en Firebird sabes cual seria la sentencia?

Antonio.xt

unread,
Mar 2, 2015, 5:18:41 PM3/2/15
to publice...@googlegroups.com

Ze Roberto, pero ese metodo no es 100% seguro, con esa sentencia obtienes el numero mayor, que podria no ser el tuyo.

Y el otro metodo te da el ultimo numero generado por ti, independientemente si hay otros.

Antonio.xt

unread,
Mar 2, 2015, 5:54:51 PM3/2/15
to publice...@googlegroups.com

Tqanyouman, FireBird aunque si maneja columnas autoincrementales, no funcionan igual que en MSSQL o MySQL, aqui creo que la columna es una columna normal, pero el Id autoincremental lo obtienes por medio de un "GENERADOR", y creo que este te da el valor al hacer el insert, y encontre que lo puedes obtener con un TRIGGER:

set term !! ;
CREATE TRIGGER TuTabla_BI FOR {TuTabla}
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
if (NEW.ID is NULL) then NEW.ID = GEN_ID(GEN_T1_ID, 1);
END!!
set term ; !!

Antonio Meza

unread,
Mar 2, 2015, 6:35:08 PM3/2/15
to publice...@googlegroups.com
En firebird tienes que usar Returning  en tu Insert into ejemplo

= sqlexec(handle,"insert into (campo1, campo2) values (valor1,valor2) returning id","tabla")

Luego vas a obtener un cursor llamado Tabla con el campo ID, y ahí tienes el ultimo Id insertado en Firebird.

saludos
Antonio Meza


El lunes, 2 de marzo de 2015, 16:13:59 (UTC-6), Tqanyouman escribió:

Antonio Meza

unread,
Mar 2, 2015, 6:39:09 PM3/2/15
to publice...@googlegroups.com
Hola Saul, seria asi

=sqlexec(handle,"SELECT LAST_INSERT_ID() as id","tabla")

Obtienes un cursor llamado tabla con un campo llamado ID y ahí tienes el valor. Tabla y ID puede ser cualquier nombre. nunca uses MAX() u otra forma que cuente registros.

saludos
Antonio Meza

El lunes, 2 de marzo de 2015, 15:49:39 (UTC-6), Saúl Piña escribió:

Esteban H

unread,
Mar 2, 2015, 6:41:00 PM3/2/15
to publice...@googlegroups.com

Exacto Antonio, así como lo describiste es.

En Firebird en el momento de definir un campo en la tabla tiene una opción q es Autoincremet value y al tildarla automáticamente define un Trigger y un Generator p ese campo y no debes preocuparte mas x el valor de ese campo es automáticamente generado, muy buena opción p usarlo como primary key, luego de haber hecho esto. Adjunto un ejemplo de una tabla.

 

 

Saludos.

 

Esteban.

image001.jpg

Saúl Piña

unread,
Mar 3, 2015, 9:34:26 AM3/3/15
to publice...@googlegroups.com
Buenos y feliz martes 03 Marzo 2015...

Empiezo a probar el ejemplo del buen amigo Antonio Meza... y asi sucesivamente..

gracias comunidad..

Les explico un poco mas al respecto:  
El usuario o varios usuarios a la vez en distintos equipos se capturan todos los datos de un ciudadano, entonces al final de la captura el sistema debe mostrar un Número

Saúl Piña

unread,
Mar 3, 2015, 9:43:20 AM3/3/15
to publice...@googlegroups.com
Me faltó comentar que el numero es de un campo incremental, entonces, el sistema debe mostrar una vez guardado los datos, cual ID INCREMENTAL asignó para ese registro.
recordando que son mas de 15 equipos capturando al mismo tiempo. En resumen:

No me sirve saber cual es el ultimo ID siguiente o el ID a Incrementar...sino que necesito el ID QUE MYSQL ASIGNÓ a la captura justo despues de hacer insert into...o de captura del registro en cuestion, para mostrar en pantalla y que el capturista pueda anotar el Número de ID de su captura..

Gracias.

Saúl Piña

unread,
Mar 3, 2015, 9:59:44 AM3/3/15
to publice...@googlegroups.com
Me muestra un "cero" en la consulta, uds saben porqué?

acepto sugerencias.

Antonio Meza

unread,
Mar 3, 2015, 10:49:16 AM3/3/15
to publice...@googlegroups.com
Hola saul, puedes mostrar el código donde mandas a guardar ya que después de mandar el Sql Insert Into, debes generar otro consulta SQL que es el Select que te envié para obtenerlo, este valor es por conexión, de esta forma cada usuario en la red obtendrá el que le corresponde sin importar quien guardo primero o quien guardo después.

Si envías un Update o Delete siempre vas a obtener 0 en la consulta, puesto que solo se obtiene un valor si enviaste un Insert Into.

saludos

Saúl Piña

unread,
Mar 3, 2015, 11:34:30 AM3/3/15
to publice...@googlegroups.com
Saludos, Este es el codigo:

=SQLSETPROP(lhandle,'Transactions',1)
        lcIns="INSERT INTO esoc.estudios"+;
        "(fecha, hora, id_area, area, servicio, entrev, grupo, elector, otra_iden, "+;
        "nombres, apaterno, amaterno, ncompleto, calle, ext, interior, domicilio,"+;
        "colonia, fnac, telefono, lnac, ocupacion, telefono, sexo, edo, "+;
        "edo_civil, edo_civil2, ocup, ocup2, escolar, escolar2, gpo_fam, gpo_fam2,"+;
        "vivienda, vivienda2, dormit, dormit2, serv_1a, serv_1b, serv_2a, serv_2b, serv_3a, serv_3b, serv_4a, serv_4b, medicos, medicos2,"+;
        "ingreso1, ingreso2, ingreso3, ingotros, ingresot, ing_fam, ing_fam2,"+;
        "egreso1, egreso2, egreso3, egreso4, egreso5, egresot, eg_fam, eg_fam2,"+;
        "calif1, calif2, calif3, calif4, calif5, calif6, calif7, calif8, calif9, calif10, total_cali,"+;
        "comen, acred, revision, seccion, elec5, capturo, imag1, imag2, imag3, imag4, latg1, long1)"+;
        "values (?d2, ?d3, ?d4, ?d5, ?d6, ?d7, ?d8, ?d9, ?d10, "+;
        "?d11, ?d12, ?d13, ?d13a, ?d14, ?d15, ?d16, ?d16a,"+;
        "?d17, ?d18, ?d18a, ?d19, ?d20, ?d21, ?d22,"+;
        "?d60, ?d61, ?d62, ?d63, ?d64, ?d65, ?d66, ?d67,"+;
        "?d68, ?d69, ?d70, ?d71, ?d72, ?d73, ?d74, ?d75, ?d76, ?d77, ?d78, ?d79, ?d80, ?d81,"+;
        "?d82, ?d83, ?d84, ?d85, ?d86, ?d87, ?d88,"+;
        "?d89, ?d90, ?d91, ?d92, ?d92a, ?d93, ?d94, ?d95,"+;
        "?d96, ?d97, ?d98, ?d99, ?d100, ?d101, ?d102, ?d103, ?d104, ?d105, ?d106,"+;
        "?d120, ?d121, ?d122, ?d123, ?d124, ?d125, ?d130, ?d131, ?d132, ?d133, ?d134, ?d135)"
            *WAIT WINDOW "Datos Agregados con éxito"  TIMEOUT .8
        =sqlexec(lhandle,"SELECT LAST_INSERT_ID() as id","lcID")

        SELECT lcID
        *brow
        LOCAL lcUltimoID
        lcUltimoID=tabla.id
        thisform.t1.value=lcUltimoID
        MESSAGEBOX("El número de Estudio Asignado es"+CHR(13)+CHR(13)+ALLTRIM(STR(lcUltimoID)),0+64,"Número de Folio Asignado")   

       

Gracias!!!

Antonio Meza

unread,
Mar 3, 2015, 12:03:51 PM3/3/15
to publice...@googlegroups.com
Saul, estas declarando una variable para el inser into, pero te falta enviarla al servidor por esa razón te devuelve 0, porque te falta el Sqlexec que envía el insert into.

saludos

Rene Ricardo

unread,
Mar 3, 2015, 12:10:24 PM3/3/15
to Grupo Visual Fox
Yo lo que hago es un procedimiento almacenado donde inserto en la tabla y para saber cual es la llave después del INSERT coloco la siguiente instrucción

SELECT @@IDENTITY As Ultimo

donde Ultimo, es el nombre del campo

Ejemplo
CREATE PROCEDURE pa_Insert_tabla
@cParametro1                  char(10),
@cParametro2  char(20)
AS
BEGIN
-
INSERT INTO TABLA (Campo1, Campo2)
VALUES (@cParametro1, @cParametro2)

SELECT @@IDENTITY As Ultimo

END



--
Tel. 2510-8619 

Víctor Hugo Espínola Domínguez

unread,
Mar 3, 2015, 12:17:54 PM3/3/15
to publice...@googlegroups.com
Hola René Ricardo

Mira este enlace: https://msdn.microsoft.com/es-es/library/ms190315.aspx

Saludos,
Víctor.
Lambaré - Paraguay.

Antonio Meza

unread,
Mar 3, 2015, 12:30:20 PM3/3/15
to publice...@googlegroups.com
Por cierto con FoxyDb todas esas lineas de código que tienes solo hubieras escrito lo siguiente:

odb.Update("estudios",.t.)
thisform.t1.value= odb.id_Last

saludos
Antonio Meza

Saúl Piña

unread,
Mar 3, 2015, 1:13:15 PM3/3/15
to publice...@googlegroups.com
Ouch... lo se Antonio, pero de verdad que quisiera tener el tiempo para dedicarle al 100 y comprender Foxydb...

Por cierto, y para animarnos a usar la herramienta, aparte de ti, alguien mas a quien preguntar y que ya esté utilizando foxy?

Saludos.

Saúl Piña

unread,
Mar 3, 2015, 2:04:59 PM3/3/15
to publice...@googlegroups.com
oYE PERO NO ES UN UPDATE, SINO UN INSERT INTO...

me sigue apareciendo en "cero" la consulta

Antonio Meza

unread,
Mar 3, 2015, 5:29:26 PM3/3/15
to publice...@googlegroups.com
Saul, el ejemplo que te puse de update es para FoxyDb, es una función que engloba cualquier comando como delete, update, insert into.

El error que tienes en tu código es que no estas enviando la variable, te falta un SQLEXEC antes del Sqlexec que mandas el select last.., no se si me explico??, dicho de otra forma

* Inicias una transacción automática
* Declaras la variable lcIns="INSERT INTO esoc.estud......
* Luego mandas a leer el ultimo id insertado =sqlexec(lhandle,"SELECT LAST_INSER
* Muestras el resultado y te da 0

Que te falta, pues mandar el SQL con la instrucción Insert into, te lo marco en rojo

* Inicias una transacción automática
* Declaras la variable lcIns="INSERT INTO esoc.estud......
* SQLEXEC(handle,lcIns)
* Luego mandas a leer el ultimo id insertado =sqlexec(lhandle,"SELECT LAST_INSER
* Muestras el resultado y te da 0

saludos
Antonio Meza

Eric Natareno Guerra

unread,
Mar 3, 2015, 7:10:02 PM3/3/15
to publicesvfoxpro

Gracias por su tiempo amigos voy a probar las sugerencias (FireBird)

Antonio Meza

unread,
Mar 3, 2015, 8:03:18 PM3/3/15
to publice...@googlegroups.com
Te recomiendo la librería FoxyDb que trabaja con Firebird, Mysql y Mariadb.

https://foxydb.wordpress.com/

saludos
Antonio Meza

Eric Natareno Guerra

unread,
Mar 3, 2015, 10:00:12 PM3/3/15
to publicesvfoxpro

Gracias Antonio lo haré pues he leído que es muy buena, gracias por compartirla

Germán Montini

unread,
Mar 4, 2015, 8:20:59 AM3/4/15
to publice...@googlegroups.com
Hola, con firebird proba esto:
 
=SQLSETPROP(lhandle,'Transactions',1)
        lcIns="INSERT INTO esoc.estudios"+;
        "(fecha, hora, id_area, area, servicio, entrev, grupo, elector, otra_iden, "+;
        "nombres, apaterno, amaterno, ncompleto, calle, ext, interior, domicilio,"+;
        "colonia, fnac, telefono, lnac, ocupacion, telefono, sexo, edo, "+;
        "edo_civil, edo_civil2, ocup, ocup2, escolar, escolar2, gpo_fam, gpo_fam2,"+;
        "vivienda, vivienda2, dormit, dormit2, serv_1a, serv_1b, serv_2a, serv_2b, serv_3a, serv_3b, serv_4a, serv_4b, medicos, medicos2,"+;
        "ingreso1, ingreso2, ingreso3, ingotros, ingresot, ing_fam, ing_fam2,"+;
        "egreso1, egreso2, egreso3, egreso4, egreso5, egresot, eg_fam, eg_fam2,"+;
        "calif1, calif2, calif3, calif4, calif5, calif6, calif7, calif8, calif9, calif10, total_cali,"+;
        "comen, acred, revision, seccion, elec5, capturo, imag1, imag2, imag3, imag4, latg1, long1)"+;
        "values (?d2, ?d3, ?d4, ?d5, ?d6, ?d7, ?d8, ?d9, ?d10, "+;
        "?d11, ?d12, ?d13, ?d13a, ?d14, ?d15, ?d16, ?d16a,"+;
        "?d17, ?d18, ?d18a, ?d19, ?d20, ?d21, ?d22,"+;
        "?d60, ?d61, ?d62, ?d63, ?d64, ?d65, ?d66, ?d67,"+;
        "?d68, ?d69, ?d70, ?d71, ?d72, ?d73, ?d74, ?d75, ?d76, ?d77, ?d78, ?d79, ?d80, ?d81,"+;
        "?d82, ?d83, ?d84, ?d85, ?d86, ?d87, ?d88,"+;
        "?d89, ?d90, ?d91, ?d92, ?d92a, ?d93, ?d94, ?d95,"+;
        "?d96, ?d97, ?d98, ?d99, ?d100, ?d101, ?d102, ?d103, ?d104, ?d105, ?d106,"+;
        "?d120, ?d121, ?d122, ?d123, ?d124, ?d125, ?d130, ?d131, ?d132, ?d133, ?d134, ?d135) RETURNING ID INTO IDRETORNO"
        =sqlexec(lhandle, lclns, "lcID")
    && EL ID QUE APARECE COMO RETURNING ES EL NOMBRE DEL CAMPO ID, EN TU CASO PUEDE SER IDUNICO O NO SE COMO SE LLAMARA, MODIFICALO

            *WAIT WINDOW "Datos Agregados con éxito"  TIMEOUT .8

        SELECT lcID
        *brow
        LOCAL lcUltimoID
        lcUltimoID=lclD.idRETORNO   && EL NOMBRE DEL CURSOR Y LA COLUMNA IDRETORNO QUE ES LA VARIABLE

        thisform.t1.value=lcUltimoID
        MESSAGEBOX("El número de Estudio Asignado es"+CHR(13)+CHR(13)+ALLTRIM(STR(lcUltimoID)),0+64,"Número de Folio Asignado")    

       
Prueba de esta manera.

Saúl Piña

unread,
Mar 4, 2015, 9:30:26 AM3/4/15
to publice...@googlegroups.com
Saludos, voy a probar el ejemplo Antonio, te agradezco mucho...

te aviso si tengo alguna duda..

Eric Natareno Guerra

unread,
Mar 4, 2015, 10:13:02 AM3/4/15
to publicesvfoxpro

Gracias German me sera de gran utilidad

Arturo Zamudio

unread,
Mar 7, 2015, 4:09:47 PM3/7/15
to publice...@googlegroups.com
creo que la manera mas simple es hacer un select

sqlexec(fireconex,'select max(id) from tu_tabla','cursor')

Víctor Hugo Espínola Domínguez

unread,
Mar 7, 2015, 4:31:45 PM3/7/15
to publice...@googlegroups.com
Hola Arturo

Esa NO es la manera más fácil, es una de las formas de obtener en algunos casos el ID generado por otro usuario.

Saludos,
Víctor.
Lambaré - Paraguay.

Arturo Zamudio

unread,
Mar 7, 2015, 4:41:12 PM3/7/15
to publice...@googlegroups.com

Mmm pues empleando algo de logica:
Antes de hacer yo el insert, consulto el ultimo id, y en base a ese id, puedo determinar cual id fue el aproximadamente  tomo mi registro

Víctor Hugo Espínola Domínguez

unread,
Mar 7, 2015, 4:52:56 PM3/7/15
to publice...@googlegroups.com

Eric Natareno Guerra

unread,
Mar 7, 2015, 7:59:28 PM3/7/15
to publicesvfoxpro

Mmmmm Arturo, pero no debe ser aproximado, sino el numero debe ser exactamente el que generaste y no el de otro usuario

Arturo Zamudio

unread,
Mar 7, 2015, 8:26:54 PM3/7/15
to publice...@googlegroups.com

Por ejemplo, si lo qie estoy tomando es una orden de servicio, hay un dato que no va a cambiar, que seria el no de cliente. En ese caso haria el select de la sig manera:
Sqlexec(fireconex,"select max(id) from mitabla where no_cliente=?no_cliente'',"cursor ")
Con eso tendría el id exacto que estoy buscando (creo yo)

Antonio.xt

unread,
Mar 9, 2015, 11:39:12 AM3/9/15
to publice...@googlegroups.com

Arturo, pero y si otro usuario tambien hace una orden del mismo cliente? El riesgo existe ahi tambien.

No hay como la funcion que te regresa el ultimo id generado por ti.

En MS SQL Server
SELECT @@IDENTITY as [MiUltimo_Id]

En MySQL
SELECT LAST_INSERT_ID();

Arturo Zamudio

unread,
Mar 9, 2015, 2:01:10 PM3/9/15
to publice...@googlegroups.com
En eso no habia pensado... Es lo bueno de estar en un grupo, varias cabezas ´piensan mejor que una (y mas cuando ya nos embotamos... jejejeje
)

Víctor Hugo Espínola Domínguez

unread,
Mar 9, 2015, 2:13:59 PM3/9/15
to publice...@googlegroups.com
Hola Antonio

Saludos,
Víctor.
Lambaré - Paraguay.

Carlos Miguel FARIAS

unread,
Mar 10, 2015, 11:17:59 AM3/10/15
to Grupo Fox
Dice si está en el mismo SP, o es en dos corridas del mismo SP. Porque si el control lo hace por SP, dos usuarios acceden al mismo SP para obtener el ultimo id, como es el mismo, obtienen el mismo para distintas transacciones.
Si lo maneja por corrida, les daría si diferentes.
Como es?

Víctor Hugo Espínola Domínguez

unread,
Mar 10, 2015, 12:58:55 PM3/10/15
to publice...@googlegroups.com
Hola Miguel

Según mi interpretación tanto @@IDENTITY como SCOPE_IDENTITY() funcionan correctamente aunque haya alta concurrencia de usuarios, donde @@IDENTITY devuelve valores incorrectos es cuando se desencadena un TRIGGER que efectúa un INSERT en otra tabla, en ese caso @@IDENTITY devuelve el último ID generado, es decir el ID asignado a la tabla involucrada en el TRIGGER.

Conclusión: En Sql Server se DEBE usar SCOPE_IDENTITY() para obtener el último ID generado.

Saludos,
Víctor.
Lambaré - Paraguay.

Germán Montini

unread,
Mar 12, 2015, 12:02:10 AM3/12/15
to publice...@googlegroups.com
Hay dos campos que no se repetirian para dos terminales, que serian fecha y hora, por que no grabas esos valores en la tabla y cuando haces la consulta lo incluyes en el where?
 

From: Antonio.xt
Sent: Monday, March 09, 2015 12:39 PM
Subject: Re: [vfp] Re: obtener el ultimo id registrado

Carlos Miguel FARIAS

unread,
Mar 12, 2015, 1:46:16 PM3/12/15
to Grupo Fox
Si las dos terminales tienen sincronizados los relojes con la red, puede repetirse.
Había comentado en post anteriores de usar como identificador interno un campo que incluya fecha/hora con milisegundos terminal y usuario. De esa manera, no tenes forma de conflicto, aunque cargues los datos fuera de la red y luego los juntes.
Por supuesto que para documentos con numeración legal, tienes que tener una tabla aparte donde puedas bloquear cada tipo de transacción, obtener el nuevo valor, mandar a imprimir y liberar la tabla de numeraciones.
Saludos: Miguel, La Pampa (RA)

Jaime Cardona

unread,
Mar 12, 2015, 3:01:19 PM3/12/15
to publice...@googlegroups.com
Hola que tal lo que yo antes de insertar hago un bloqueo de la tabla a la que insertare el registro, con esta instruccion, asi aseguro que nadie escriba a la tabla mientras obtengo el id que sigue

loocktable('tabla', "WRITE")

*Depues saco el id que seguira con esta funcion
lidsig = idsig('tabla')
*ahora si tienes el id que continua en la variable lidsig
* agregas registro a la tabla

*quito el bloqueo 
unlocktable()

Te anexo las funciones que uso ojala te sirvan

Saludos



*-------------------------------
* lock table
*-------------------------------
Procedure locktable
Parameters ptabla, ptipo
TEXT TO strsql NOSHOW TEXTMERGE
LOCK TABLES <<ptabla>> <<ptipo>>;
ENDTEXT
=creacursor(strsql, [], 1)
Endproc
*-------------------------------
* unlock table
*-------------------------------
Procedure unlocktable
TEXT TO strsql NOSHOW TEXTMERGE
unLOCK TABLES;
ENDTEXT
=creacursor(strsql, [], 1)
Endproc
*----------------------------------------------------------------------------------
* FUNCION  q regresa el id autonumerico de una tabla
*-----------------------------------------------------------------------------------
Function idsig
Parameters ptabla
TEXT TO strsql NOSHOW TEXTMERGE
SELECT AUTO_INCREMENT as sigue FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'facturasoft' AND TABLE_NAME = '<<ptabla>>'
ENDTEXT
creacursor(strsql,"maxfolio",1)
If Reccount('maxfolio')=0 Or Isnull(maxfolio.sigue)
Return 1
Else
Return Cast(maxfolio.sigue As Integer)
Endif
Endfunc

*------------------------
Function creacursor
*------------------------
*_Screen.cconectainventario es el controlador que se genera de la cadena d conexion de odbc a mysql
Parameters psql_str, pcursor, pdb
If _Screen.cconectainventario< 0
= Messagebox('Hubo un error en la conexion al servidor de datos', 16, 'MySQL Error')
Else
*     SQLPREPARE(_Screen.cconectainvent,psql_str,pcursor)
= SQLSetprop(_Screen.cconectainventario, 'Transactions', 2)  && Manual transactions
a = SQLExec(_Screen.cconectainventario,psql_str,pcursor)
Return a
Endif
endfunc
Reply all
Reply to author
Forward
0 new messages