Test Foro de elhacker.net SMF 2.1

Programación => Desarrollo Web => Mensaje iniciado por: Leguim en 26 Julio 2019, 18:00 PM

Título: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: Leguim en 26 Julio 2019, 18:00 PM
Buenos días, básicamente quería saber como podría editar un id (AUTO_INCREMENT) de una tabla ya es conocido que son valores únicos e irrepetibles. Lo que busco es que al momento de realizar la consulta, el registro al que intento editar "UPDATE" tenga un id más renovada es decir mas grande como si fuera que cree ese registro por primera vez. Espero haberme podido explicar bien.. Gracias
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: MinusFour en 26 Julio 2019, 18:34 PM
No estoy muy seguro, pero creo que si utilizas NULL para el campo con AUTO_INCREMENT (y le has puesto NOT_NULL al campo con AUTO_INCREMENT) te genera un nuevo número.
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: Leguim en 26 Julio 2019, 18:50 PM
Cita de: MinusFour en 26 Julio 2019, 18:34 PM
No estoy muy seguro, pero creo que si utilizas NULL para el campo con AUTO_INCREMENT (y le has puesto NOT_NULL al campo con AUTO_INCREMENT) te genera un nuevo número.

Había buscado en internet antes y se decía algo de que al hacer eso de poner null da un id = 0 pero lo voy a probar haber que tal y te digo.
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: MinusFour en 26 Julio 2019, 18:58 PM
Cita de: MiguelCanellas en 26 Julio 2019, 18:50 PM
Había buscado en internet antes y se decía algo de que al hacer eso de poner null da un id = 0 pero lo voy a probar haber que tal y te digo.

Va a depender de la base de datos pero está en la documentación de MySQL.

(https://i.imgur.com/XKjQEWZ.png)

https://dev.mysql.com/doc/mysql-tutorial-excerpt/5.7/en/example-auto-increment.html
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: WHK en 26 Julio 2019, 21:05 PM
Creo que tu tabla tiene problemas de definición, ejecuta un DESCRIBE nombrdelatabla; y peganos el resultado para ver porque no está incrementando los valores de manera automática.
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: Leguim en 27 Julio 2019, 03:29 AM
No pude poner el NOT_NULL no se donde tengo que ir para eso.

Cita de: WHK en 26 Julio 2019, 21:05 PM
Creo que tu tabla tiene problemas de definición, ejecuta un DESCRIBE nombrdelatabla; y peganos el resultado para ver porque no está incrementando los valores de manera automática.

Me salió esto..

Field | Type | Null | Key | Default | Extra

id | int(50) | NO | PRI | NULL | auto_increment
nombre | varchar(25) | YES | NULL
apellido | varchar(25) | YES | NULL
email | varchar(200) | YES | NULL
contrasena | varchar(200) | YES | NULL
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: WHK en 27 Julio 2019, 05:04 AM
Ok...

id | int(50) | NO | PRI | NULL | auto_increment

Tu columna id dice que si es numérico y autoincrementable pero también dice que puede ser nulo y eso está mal, porque si no lo defines al insertar un valor entonces queda nulo en ves de crear el valor numérico autoincrementado.

Debes modificarlo e indicarle que no puede ser nulo:

ALTER TABLE nombredelatabla MODIFY id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;

Ojo, cuando lo hags te dará un error si tienes registros nulos, para aplicar ese cambio debes asignar un valor a cada registro nulo.

Otro cuidado es el valor de inicio del autoincrementable, probablemente la base de datos no ha utilizado la función de autoincremento por lo cual el primer valor a asignar al crear un registro sea el 1 y luego el 2 y así, pero si ya tienes esos valores utilizados entonces tendrás un problema.

Para solucionar esto debes modificar el valor del autoincrementable para que comience a partir del siguiente valor mas grande que tengas:

ALTER TABLE nombredelatabla AUTO_INCREMENT = 100;

Donde 100 es el valor que comenzará a utilizar.

Si quieres saber tu valor máximo actual puedes utilizar:

SELECT MAX(id) FROM nombredelatabla;

A eso le sumas uno y ya.

Para saber si tienes registros nulos:

SELECT * FROM nombredelatabla WHERE id IS NULL LIMIT 100;

Saludos.
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: Leguim en 27 Julio 2019, 05:12 AM
¡Muchas gracias a los dos por la mano que me dieron con esto!  ;-)
MIL GRACIAS!
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: EdePC en 27 Julio 2019, 07:03 AM
Saludos,

- He estado haciendo pruebas en mi MySQL 5.6.35 y veo que cuando se actualiza un valor auto_increment usando UPDATE el contador interno que usa MySQL no se actualiza y se queda como estaba, luego de intentar INSERT un nuevo registro da un error ya que el contador se quedo atrás, sin embargo el contador se actualiza luego del error y permite insertar el nuevo registro en el siguiente intento:


mysql> DESCRIBE animals;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM animals;
+----+------+
| id | name |
+----+------+
|  1 | dog  |
|  3 | lax  |
|  4 | wolf |
|  7 | cow  |
|  8 | bull |
|  9 | lion |
| 10 | cat  |
+----+------+

mysql> SET @newId = ( SELECT MAX(id) + 1 FROM animals );
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE animals SET id = @newId, name = 'rat' WHERE name = 'lax';
Query OK, 1 row affected (0.14 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM animals;
+----+------+
| id | name |
+----+------+
|  1 | dog  |
|  4 | wolf |
|  7 | cow  |
|  8 | bull |
|  9 | lion |
| 10 | cat  |
| 11 | rat  |
+----+------+
7 rows in set (0.00 sec)

mysql> INSERT INTO animals VALUES ( NULL, 'parrot' );
ERROR 1062 (23000): Duplicate entry '11' for key 'PRIMARY'

mysql> INSERT INTO animals VALUES ( NULL, 'parrot' );
Query OK, 1 row affected (0.15 sec)

mysql> SELECT * FROM animals;
+----+--------+
| id | name   |
+----+--------+
|  1 | dog    |
|  4 | wolf   |
|  7 | cow    |
|  8 | bull   |
|  9 | lion   |
| 10 | cat    |
| 11 | rat    |
| 12 | parrot |
+----+--------+
8 rows in set (0.00 sec)


- Pues habrá que tener esto en cuenta y actualizar el contador a mano como dice WHK usando:

ALTER TABLE animals AUTO_INCREMENT = @newId + 1;

-- PERO no funciona, esa instrucción no soporta variables XD, al menos no en mi MySQL 5.6.35, la alternativa es usar una Sentencia Preparada, los pasos completos a continuación:


mysql> SELECT * FROM animals;
+----+--------+
| id | name   |
+----+--------+
|  4 | wolf   |
|  7 | cow    |
|  8 | bull   |
|  9 | lion   |
| 10 | cat    |
| 11 | rat    |
| 12 | parrot |
| 13 | condor |
| 14 | tiger  |
| 15 | fly    |
+----+--------+
10 rows in set (0.00 sec)

mysql> SET @newId = ( SELECT MAX(id) + 1 FROM animals );
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @newId;
+--------+
| @newId |
+--------+
|     16 |
+--------+
1 row in set (0.00 sec)

mysql> UPDATE animals SET id = @newId, name = 'gorilla' WHERE name = 'rat';
Query OK, 1 row affected (0.14 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  4 | wolf    |
|  7 | cow     |
|  8 | bull    |
|  9 | lion    |
| 10 | cat     |
| 12 | parrot  |
| 13 | condor  |
| 14 | tiger   |
| 15 | fly     |
| 16 | gorilla |
+----+---------+
10 rows in set (0.00 sec)

mysql> ALTER TABLE animals AUTO_INCREMENT = @newId + 1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@newId + 1' at line 1

mysql> SET @sql = CONCAT('ALTER TABLE animals AUTO_INCREMENT = ', @newId + 1);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @sql;
+-----------------------------------------+
| @sql                                    |
+-----------------------------------------+
| ALTER TABLE animals AUTO_INCREMENT = 17 |
+-----------------------------------------+
1 row in set (0.00 sec)

mysql> PREPARE st FROM @sql; EXECUTE st;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

Query OK, 0 rows affected (0.13 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> INSERT INTO animals VALUES ( NULL, 'mouse' );
Query OK, 1 row affected (0.13 sec)

mysql> SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  4 | wolf    |
|  7 | cow     |
|  8 | bull    |
|  9 | lion    |
| 10 | cat     |
| 12 | parrot  |
| 13 | condor  |
| 14 | tiger   |
| 15 | fly     |
| 16 | gorilla |
| 17 | mouse   |
+----+---------+
11 rows in set (0.00 sec)
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: Leguim en 27 Julio 2019, 09:36 AM
Hola EDE!

Digamos no sirve poner a la columna "id" NOT_NULL y luego ponerlo NULL o sería mejor usar ese método que me mostraste?
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: EdePC en 27 Julio 2019, 17:44 PM
- Por defecto los PRIMARY KEY son siempre NOT NULL y UNIQUE, no tendría sentido ni posibilidad el tener una Clave Primaria con valores repetidos o nulos XD, me parece que WHK no interpretó bien la estructura de la tabla (ver tabla abajo).

- Aunque al final lo que se quiere lograr es rescatar los valores de los campos de un registro, eliminar dicho registro y volverlo a insertar para que tenga un id generado nuevo. Esto lo puedes hacer tal cual entendiendo esto o atacarlo de otras maneras, por ejemplo usar variables para rescatar los valores, eliminar el registro, cambiar los valores de las variables ser necesario, e insertar el nuevo registro preparado.

-- Por ejemplo:

mysql> DESCRIBE animals;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM animals;
+----+------+
| id | name |
+----+------+
|  1 | cat  |
|  2 | dog  |
|  3 | rat  |
|  4 | bull |
|  5 | lion |
+----+------+
5 rows in set (0.00 sec)

mysql> SELECT @id := id, @name := name FROM animals WHERE id = 3;
+-----------+---------------+
| @id := id | @name := name |
+-----------+---------------+
|         3 | rat           |
+-----------+---------------+
1 row in set (0.01 sec)

mysql> SELECT @id;
+------+
| @id  |
+------+
|    3 |
+------+
1 row in set (0.00 sec)

mysql> SELECT @name;
+-------+
| @name |
+-------+
| rat   |
+-------+
1 row in set (0.00 sec)

mysql> SET @name = 'tiger';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @name;
+-------+
| @name |
+-------+
| tiger |
+-------+
1 row in set (0.00 sec)

mysql> DELETE FROM animals WHERE id = @id;
Query OK, 1 row affected (0.05 sec)

mysql> INSERT INTO animals ( name ) VALUES ( @name );
Query OK, 1 row affected (1.23 sec)

mysql> SELECT * FROM animals;
+----+-------+
| id | name  |
+----+-------+
|  1 | cat   |
|  2 | dog   |
|  4 | bull  |
|  5 | lion  |
|  6 | tiger |
+----+------+
5 rows in set (0.00 sec)


Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: WHK en 27 Julio 2019, 18:59 PM
Te estás ahogando en un vaso de agua. Si vas a hacer inserción manual de identificadores te meterás en un problema bastante complicado ya que para eso existen los bloqueos de tabla. En bases de datos con muchos registros comenzarán a duplicarse los identificadores porque mientras que calculas el valor para autoincrementar vendrá otra conexión en paralelo y hará el mismo calculo haciendo que ambos registros guarden el mismo valor provocando que el último no se pueda escribir.

Por eso mysql de manera nativa realiza un bloqueo de tablas para reservar su uso mientras realiza el calculo de autoincremento, a demás de eso cuenta con una pila interna de instrucciones para evitar que peticiones asyncronas obtengan un mismo identificador.

Primero lo primero, todos tus id de todas las tablas deben ser autoincrementables, luego debes tomar el valor máximo y dárselo como subquery, evita en lo posible utilizar variables y procedimientos almacenados.

Si es una base de datos nueva entonces eliminala y vuelvela a crear con las propiedades que corresponden.

Saludos.
Título: Re: [Pregunta]: Update en un ID AUTO_INCREMENT
Publicado por: MinusFour en 27 Julio 2019, 21:41 PM
Creo que es muy raro que Update no actualize el registro para auto incrementar en la tabla. Pero si es así, la única forma va tener que ser reinsertar los valores en la tabla. Yo lo he probado con MariaDB 10.4 y los inserts funcionan bien después de hacer un update al campo primario. De todas formas, poniendo NULL en UPDATE no funciona.

MAX puede funcionar pero se vuelve mas complicado si quieres actualizar multiples registros a la vez. Yo creo que sería mejor volver a reinsertar los valores.

Francamente, no le veo valor a actualizar la ID de los registros.