reiniciar numeros autoincrementables en mysql?

1,339 views
Skip to first unread message

Saúl Piña

unread,
Dec 17, 2014, 4:09:09 PM12/17/14
to publice...@googlegroups.com
Saludos, tengo una duda, hay veces que debo eliminar un registro de una tabla de mysql con un campo ID autoincremental, pero veo que al eliminar un registro, digamos el 15, el siguiente registro que yo agrego, me muestra el numero 16 en el campo ID. y me gustaria que fuese de nuevo el num 15

Es posible o no es posible? 

gracias.

Carlos Miguel FARIAS

unread,
Dec 17, 2014, 5:26:05 PM12/17/14
to Grupo Fox

Poder se puede. Como administrador y para casos excepcionales. Pero si necesitas hacer en forma habitual, no estas usando apropiadamente un autoincremental y si hay usuarios activos al momento de la aplicación del de incremento, habrá algunos problemas
Saludos: Miguel, La Pampa (RA)

Antonio.xt

unread,
Dec 17, 2014, 5:35:45 PM12/17/14
to publice...@googlegroups.com

Me parece que no se puede hacer eso directamente.
Cuando en una tabla con campo antoincremental borras el contenido con DELETE, el ID autoincremental conserva su numero; si quieres que vuelva a iniciar al eliminar el contenido de la tabla es haciendo TRUNCATE TABLE {tabla}, eso en SQL Server, no se en MySQL.

Si hay metodos, pero creo que no hay un comando que lo haga directamente, pero si vas a hacer eso con frecuencia no te conviene, solo si es un caso especial.

Podrias pasar el contenido de la tabla a una tabla temporal, luego truncar la tabla y por ultimo regresar el contenido a la tabla.

En SQL Server existe la instruccion "DBCC CHECKIDENT (<nombre_tabla>, RESEED,0)"

Pero en MySQL no se si es la misma...

Christian López Gómez

unread,
Dec 17, 2014, 5:39:28 PM12/17/14
to publice...@googlegroups.com
el codigo para ello es este ALTER TABLE nombre_tabla AUTO_INCREMENT=1


saludos

--
Atentamente.
Ing. Christian López Gómez
Desarrollador de Sistemas
Skype : christian.lopez.gomez

Depto. Sistemas
P.D. "Un buen programador nunca muere solo se pierde en un proceso"

Martin Paredes

unread,
Dec 17, 2014, 6:02:03 PM12/17/14
to publice...@googlegroups.com
en esta vida todo se puede, te paso un ejemplo que utilizo en postgresql

REINICIO 
ALTER SEQUENCE <<tabba.id>> RESTART;

ALTERO SEQUENCE
ALTER SEQUENCE <<tabba.id>> START WITH <<numero>>;

esto lo utilizo mucho cuando inicia-lizo una BD, de pruebas a producción.

aquí esta el código.
SET SAFETY OFF
RELEASE ALL
CLEAR ALL
lcserver="localhost"
lcdatabase="database"
lcuser="usuario"
lcpassword="password"
lcport="5432"
lcstringConn="Provider=MSDASQL;Driver={PostgreSQL ODBC Driver(UNICODE)}; Server="+lcserver+";Port="+lcport+";Database="+lcdatabase+";uid="+lcuser+";pwd="+lcpassword+";UseServerSidePrepare=1;MaxVarcharSize=254;UnknownsAsLongVarchar=0;TextAsLongVarchar=0;"
SQLSETPROP(0, "Displogin", 3)
_nconn=SQLSTRINGCONNECT(lcstringConn)
IF _nconn>0 THEN
   TEXT TO lcSQLcommand NOSHOW TEXTMERGE
      SELECT UPPER(tablename) AS tabla
             FROM pg_tables 
                  WHERE schemaname='mapasoft'
                        ORDER BY tablename;
   ENDTEXT
   IF SQLEXEC(_nconn, lcSQLcommand, "inicializa")>0 THEN
      SELECT inicializa
      GO TOP
      IF ! EOF() THEN
         nvan=1
         nson=RECCOUNT()
         DO WHILE ! EOF()
            SET MESSAGE TO '...Alterando Sequencia Tabla : '+ALLTRIM(STR(nvan))+' De '+ALLTRIM(STR(nson))+' ('+ALLTRIM(inicializa.tabla)+')'
            corderby=ALLTRIM(inicializa.tabla)+'.id'+ALLTRIM(inicializa.tabla)
            TEXT TO lcSQLcommand NOSHOW TEXTMERGE
               SELECT * FROM mapasoft.<<inicializa.tabla>> ORDER BY <<corderby>> DESC;
            ENDTEXT
            IF SQLEXEC(_nconn, lcSQLcommand, "cuantoshay")>0 THEN
               nhayy=1
               SELECT cuantoshay
               GO TOP
               IF ! EOF() THEN
                  x='cuantoshay.id'+ALLTRIM(inicializa.tabla)
                  nhayy=&x+1
               ENDIF
               cseq='mapasoft.'+ALLTRIM(inicializa.tabla)+'_id'+ALLTRIM(inicializa.tabla)+'_seq'
               TEXT TO lcSQLcommand NOSHOW TEXTMERGE
                  ALTER SEQUENCE <<cseq>> RESTART;
               ENDTEXT
               IF SQLEXEC(_nconn, lcSQLcommand, "")>0 THEN
                  TEXT TO lcSQLcommand NOSHOW TEXTMERGE
                     ALTER SEQUENCE <<cseq>> START WITH <<nhayy>>;
                  ENDTEXT
                  IF SQLEXEC(_nconn, lcSQLcommand, "")>0 THEN
                     TEXT TO lcSQLcommand NOSHOW TEXTMERGE
                        VACUUM ANALYZE VERBOSE mapasoft.<<inicializa.tabla>>;
                     ENDTEXT
                     IF SQLEXEC(_nconn, lcSQLcommand, "")>0 THEN
                        TEXT TO lcSQLcommand NOSHOW TEXTMERGE
                           REINDEX TABLE mapasoft.<<inicializa.tabla>>;
                        ENDTEXT
                        IF SQLEXEC(_nconn, lcSQLcommand, "")>0 THEN
                           nvan=nvan+1
                        ELSE
                           =AERROR(laError)
                           cError=laError(1,3)
                           MESSAGEBOX(cError)
                           EXIT
                        ENDIF
                     ELSE
                        =AERROR(laError)
                        cError=laError(1,3)
                        MESSAGEBOX(cError)
                        EXIT
                     ENDIF
                  ELSE
                     =AERROR(laError)
                     cError=laError(1,3)
                     MESSAGEBOX(cError)
                     EXIT
                  ENDIF
               ELSE
                  =AERROR(laError)
                  cError=laError(1,3)
                  MESSAGEBOX(cError)
                  EXIT
               ENDIF
            ELSE
               =AERROR(laError)
               cError=laError(1,3)
               MESSAGEBOX(cError)
               EXIT
            ENDIF
            SET MESSAGE TO ''
            SELECT inicializa
            SKIP            
         ENDDO
         MESSAGEBOX('Listo.')
      ELSE
         MESSAGEBOX('Error; No Se Localizo Ninguna Tabla En La Base De Datos.', 16, 'Mensaje.')
      ENDIF
   ELSE
      =AERROR(laError)
      cError=laError(1,3)
      MESSAGEBOX(cError)
   ENDIF
ELSE
   =AERROR(laError)
   cError=laError(1,3)
   MESSAGEBOX(cError)
ENDIF
SET MESSAGE TO ''
SET SAFETY ON
RELEASE ALL
CLEAR ALL
CLEAR MEMORY
RELEASE _nconn

*** espero y te sirva de referencia

salds....
Mapasac
General Escobedo, N.L., Mexico


El miércoles, 17 de diciembre de 2014 15:09:09 UTC-6, Saúl Piña escribió:

Toni Akux

unread,
Dec 17, 2014, 6:22:06 PM12/17/14
to publice...@googlegroups.com
Bueno, voy a aportar mi granito de arena, aunque no estoy seguro de hacerlo correctamente...
En primer lugar, nunca he considerado una buena opción eso de eliminar registros, ya que nunca se sabe si en futuro, esa información tendré que recuperarla.
En cuanto al incremental... Uuufff!!! Considero que esa es su función correcta, no? No considero que funcione bien de otra manera.
Yo tuve en una ocasión esa necesidad y la solventé sin auto-incremental. Simplemente hice ese control de forma manual. Es decir, muy a mi pesar, permití la eliminación de registros, asignando los nuevos Identificadores Numericos averiguando primero el máximo del campo y luego sumándole 1 al nuevo registro. Inconveniente, que hay que hacer un SELECT antes del INSERT.
Otra opción, es utilizar esto: ALTER TABLE nombre_tabla AUTO_INCREMENT='value', donde este valor será el número por el que continuará el autoincremental. Dicho esto, el mencionado valor podrás asignarlo al eliminar un registro guardando en una variable el ID del registro a eliminar, justo antes de proceder a su borrado, para después utilizar ese 'valor' asignado a la variable para hacer el ALTER TABLE y dejarlo preparado para el próximo INSERT.
Espero al menos haberte abierto un poco los ojos y te sea de ayuda esto que te indico.
Atentamente,

Antonio Meza

unread,
Dec 17, 2014, 7:45:51 PM12/17/14
to publice...@googlegroups.com
Ya te indicaron como solucionarlo, sin embargo como comentario adicional, los campos ID autoincrementables solo debes usarlos como un identificador único de un registro, que te puede servir para relacionar con otras tablas, actualizar, eliminar de forma simple por este valor autoincremental.

Los campos ID ya hablando un poco mas a fondo, los usuarios no deberían conocer estos números, ya que son identificadores de registro, y posiblemente estas confundiendo con un campo de tipo código o clave o control interno, folio, consecutivo, etc.

La estructura de mi tabla CLIENTES en MySql es la siguiente

id INT 10 autoincremental primary key
codigo CHAR 10 Consecutivo de Clientes
Cliente VarChar 100 Nombre del Cliente

Explicando lo anterior, el campo ID es autoincremental y puede saltarse si una operación de la tabla no se realizo correctamente, sin embargo incrementara siempre, y si el usuario requiere un campo numérico consecutivo para identificar a los clientes, pues para eso esta el campo CODIGO que se almacena así 0000000010, 0000000150, etc, y van consecutivo sin saltarse.

Por lo tanto el valor ID autoincremental no me interesa si va en el 10 o 15 o 5000, ya que solo me permite identificar el registro y los usuarios no tienen idea siquiera que existe este campo.

saludos
Antonio Meza


El miércoles, 17 de diciembre de 2014 15:09:09 UTC-6, Saúl Piña escribió:

Luis Maria Guayan

unread,
Dec 18, 2014, 7:10:27 AM12/18/14
to publice...@googlegroups.com
Poder se puede, pero no se debería. Pareciera que estas confundiendo la utilización de números autoincrementales con números consecutivos.

Este artículo para VFP te puede ayudar:  http://comunidadvfp.blogspot.com/2005/03/numeros-consecutivos-para-nuestras.html

En este otro para SQL Server: http://comunidadvfp.blogspot.com/2009/07/como-generar-el-numero-de-nuestros.html



Luis María Guayán
Tucumán, Argentina
_____________________________
http://comunidadvfp.blogspot.com

Carlos Miguel FARIAS

unread,
Dec 18, 2014, 7:22:09 AM12/18/14
to Grupo Fox
Coincido con Antonio: Los valores autoincrementales sirven para claves primarias simples, para relacionar tablas. Puede llegar a ser efectivas cuando puedes controlar el tamaño del campo usado por SGBD.
Si tienes una tabla que no supera los 100 registros, poder usar un tinyint como en mysql, te ahorra espacio y problemas.
En postgresql ocupan 4 o 8 bytes (depende de capacidad).
Un serial de 8 bytes permite almacenar 18 digitos.
Personalmente, prefiero usar ese espacio para guardar datos de auditoria (ya lo he comentado antes en este foro), con 18 dígitos puedo guardar quien, cuando y donde. No importa si paso de desarrollo a producción o si tengo que juntar datos de diferentes bases.
También uso dicha función en reemplazo del timestamp, ya que además del cuando se modifico el registro, me indica quien y donde.
Saludos: Miguel, la Pampa (RA)

Hugo C.

unread,
Dec 18, 2014, 10:08:30 PM12/18/14
to publice...@googlegroups.com
Estoy de acuerdo con la opinión de LuisMa, son 2 cosas diferentes..


Saludos.
Reply all
Reply to author
Forward
0 new messages