¿Quiere la siguiente identificación o la identificación de la fila que está insertando actualmente? Es decir, ¿la identificación al final del código de pago debería ser la identificación de la fila en la que se almacena el código de pago?
Mike
id de la fila que estoy insertando actualmente
faressoft
6
En ese caso, concatene los valores cuando los recupere, no cuando los inserte. Es mucho más fácil de esa manera, y descarta obtener la identificación incorrecta o tener que ejecutar una actualización; piense en lo que sucedería si otro cliente solicita la fila que acaba de insertar, antes de que la actualización haya tenido la oportunidad de ejecutarse: el cliente terminaría con un código de pago no válido. En un sistema de poco tráfico, eso podría no ocurrir, pero no veo el sentido de correr el riesgo.
Gracias por las dos primeras opciones ... Pero la tercera es solo la número dos llamada desde PHP ... No estoy seguro de qué lo hace más rápido en bases de datos grandes ...
Gerard ONeill
1
@GerardONeill lo eliminó
ravi404
3
debido a que se usa un caché para recuperar los datos de information_schema.tables, esta solución ya no funciona para mysql 8.
Puede obtener el siguiente valor de incremento automático haciendo lo siguiente:
SHOW TABLE STATUS FROM tablename LIKE Auto_increment
/*or*/SELECT`auto_increment`FROM INFORMATION_SCHEMA.TABLES
WHERE table_name ='tablename'
Tenga en cuenta que usted debe no usar esto para modificar la tabla, utilice una columna AUTO_INCREMENT de hacerlo de forma automática en su lugar.
El problema es que last_insert_id()es retrospectivo y, por tanto, se puede garantizar dentro de la conexión actual.
Este bebé es prospectivo y, por lo tanto, no es único por conexión y no se puede confiar en él.
Solo en una base de datos de conexión única funcionaría, pero las bases de datos de conexión única de hoy tienen la costumbre de convertirse en bases de datos de conexión múltiple mañana.
No lo rechacé, pero el problema al intentar usar el último valor de incremento automático es que puede que no sea el último en el momento en que lo use, sin importar qué tan rápido se lleve a cabo SELECT y el INSERT subsiguiente.
Mike
@ Mike, ¿y si se hace en una sola consulta? Algo como insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'? after insertlast_insert_id()
Usaría la
1
@binaryLV: cuanto menor sea la brecha entre SELECT e INSERT, menor será la posibilidad de que el valor haya cambiado, pero no lo descarta por completo. Imagine un sistema con miles de visitas por minuto en la base de datos: las posibilidades de que el valor haya cambiado aumentan drásticamente. El bloqueo de tablas o filas puede evitar esto si se realiza como una consulta única, pero eso depende de un comportamiento particular del motor de la base de datos que puede no estar bien documentado. Yo iría con una subsecuente UPDATEsi tuviera también. Pero prefiero concatenar los dos en el momento de la visualización y ahorrar toda la molestia.
Mike
3
SHOW TABLE STATUSespera ver database namedespués FROMy 'table name pattern'después LIKE.
x-yuri
2
debido a que se usa un caché para recuperar los datos de information_schema.tables, esta solución ya no funciona para mysql 8.
Bruno
15
Esto devolverá el valor de incremento automático para la base de datos MySQL y no verifiqué con otras bases de datos. Tenga en cuenta que si está utilizando cualquier otra base de datos, la sintaxis de la consulta puede ser diferente.
SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name ='your_table_name'and table_schema ='your_database_name';SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name ='your_table_name'and table_schema =database();
SELECCIONE AUTO_INCREMENT FROM information_schema.tables DONDE table_name = 'your_table_name' y table_schema = 'your_database_name';
LJay
10
La respuesta principal usa PHP MySQL_ para una solución, pensé que compartiría una solución PHP MySQLi_ actualizada para lograr esto. ¡No hay salida de error en este ejemplo!
$db = new mysqli('localhost','user','pass','database');$sql ="SHOW TABLE STATUS LIKE 'table'";$result=$db->query($sql);$row=$result->fetch_assoc();
echo $row['Auto_increment'];
Lanza el siguiente incremento automático que aparece en una tabla.
Tenga en cuenta que con el primer método, si se elimina el registro con la identificación más alta, luego creará un nuevo registro con la identificación que solía tener el que se eliminó.
Tom Jenkinson
y si la clave anterior se usó en otras tablas y aún se mantiene allí, puede terminar con una magia muy extraña
Tebe
el primero devuelve una identificación incorrecta si elimina el último registro insertado,
Ali Parsa
6
Solución:
CREATETRIGGER`IdTrigger` BEFORE INSERTON`payments`FOR EACH ROWBEGINSELECT AUTO_INCREMENT Into@xId
FROM information_schema.tables
WHERE
Table_SCHEMA ="DataBaseName"AND
table_name ="payments";SET NEW.`payment_code`= CONCAT("sahf4d2fdd45",@xId);END;
"DataBaseName" es el nombre de nuestra base de datos
La actualización payment_codeen el after insertdisparador parece ser la mejor opción.
binaryLV
3
No puede usar el ID mientras lo inserta, ni tampoco lo necesita. MySQL ni siquiera conoce el ID cuando inserta ese registro. Podrías simplemente guardar "sahf4d2fdd45"en la payment_codetabla y usar idy payment_codemás adelante.
Si realmente necesita que su payment_code tenga la ID, ACTUALICE la fila después de la inserción para agregar la ID.
+1 Para hacer esto un poco más explícito: si toma el valor 'último' de una columna, solo se garantiza que sea el valor más reciente en el momento exacto en que lo toma. Puede que no sea el último valor cuando se utiliza ese valor en una inserción posterior. En el caso de una columna de incremento automático, siempre existe la posibilidad de que se haya agregado otro valor entre el momento en que recuperó la identificación y el momento en que lo inserta en otro lugar. Si está haciendo referencia a una fila que acaba de insertar, usar LAST_INSERT_ID () está bien. Si está tratando de garantizar un valor único, no lo es.
Mike
@cularis, MySQL conoce la siguiente identificación de auto_increment, está listada en la information_schema.tablestabla.
Johan
1
@faressoft: Si la idea es tener un código de pago que comprenda una cadena única más la identificación de la fila que contiene ese código de pago, simplemente combine los dos cuando recupere la fila, ya sea con a SELECT ... CONCAT(payment_code, id), o en su código de aplicación. Incluso puede envolver el SELECTen a VIEW, para que siempre devuelva el valor correcto, sin preocuparse por el CONCAT en cada SELECCIÓN de su aplicación.
Mike
3
¿Para qué necesita el próximo ID incremental?
MySQL solo permite un campo de incremento automático por tabla y también debe ser la clave principal para garantizar la exclusividad.
Tenga en cuenta que cuando obtenga el siguiente ID de inserción, es posible que no esté disponible cuando lo use, ya que el valor que tiene está solo dentro del alcance de esa transacción. Por lo tanto, dependiendo de la carga en su base de datos, es posible que ese valor ya se haya utilizado para cuando llegue la siguiente solicitud.
Le sugiero que revise su diseño para asegurarse de que no necesita saber qué valor de incremento automático asignar a continuación
No es una buena idea asumir el tipo de aplicación que requiere la identificación. Hay aplicaciones como en la que estoy trabajando en este momento que necesita la siguiente ID incremental y el valor recuperado no corre peligro de ser asignado a otro script.
JG Estiot
3
Sugiero que reconsidere lo que está haciendo. Nunca experimenté un solo caso de uso en el que se requiera ese conocimiento especial. La siguiente identificación es un detalle de implementación muy especial y no contaría con que sea seguro para ACID.
Haga una transacción simple que actualice su fila insertada con la última identificación:
BEGIN;INSERTINTO payments (date, item, method)VALUES(NOW(),'1 Month','paypal');UPDATE payments SET payment_code = CONCAT("sahf4d2fdd45", LAST_INSERT_ID())WHERE id = LAST_INSERT_ID();COMMIT;
Puedo decir uno de esos casos de uso, estoy tratando de diagnosticar un problema de producción, por lo que necesito averiguar si la última fila de una tabla es realmente la última fila o si se agregó una después de la que de alguna manera se eliminó, tabla tiene un campo auto_increment, por lo que al encontrar esta información puedo concluir si la fila se eliminó o nunca se agregó.
Usman
1
Eso podría funcionar para usted, pero no confiaría en eso ya que no creo que tenga ninguna garantía al respecto: dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html " cuando la columna AUTO_INCREMENT es parte de un índice de varias columnas), los valores de AUTO_INCREMENT se reutilizan si elimina la fila con el valor de AUTO_INCREMENT más grande en cualquier grupo ".
Markus Malkusch
Gracias, información útil, también según su enlace compartido, auto_increment se puede restablecer insertando manualmente un número, así que sí, no es confiable.
Usman
2
Tiene que conectarse a MySQL y seleccionar una base de datos antes de poder hacer esto
$table_name ="myTable";$query = mysql_query("SHOW TABLE STATUS WHERE name='$table_name'");$row= mysql_fetch_array($query);$next_inc_value =$row["AUTO_INCREMENT"];
utilice "mysql_insert_id ()". mysql_insert_id () actúa sobre la última consulta realizada, asegúrese de llamar a mysql_insert_id () inmediatamente después de la consulta que genera el valor.
A continuación se muestra el ejemplo de uso:
<?php
$link = mysql_connect('localhost','username','password');if(!$link){
die('Could not connect: '. mysql_error());}
mysql_select_db('mydb');
mysql_query("INSERT INTO mytable VALUES('','value')");
printf("Last inserted record has id %d\n", mysql_insert_id());?>
Yo también estoy de acuerdo en que este es el enfoque más simple. No estoy seguro de por qué fue rechazado, pero lo compensaré con un voto a favor.
recurse
No mencioné la necesidad de la transacción, si no lo envuelve dentro de la transacción, este código es pésimo lo antes posible que se encuentre con una carga real.
Tebe
1
¿Qué pasa si se eliminó la última fila? ¿O se han eliminado varias filas más recientes?
Liam W
Las claves liberadas que no son de emisión no se usan a menos que lo especifique explícitamente
Tebe
1
usando la respuesta de ravi404:
CREATEFUNCTION`getAutoincrementalNextVal`(`TableName` VARCHAR(50))
RETURNS BIGINT
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''BEGINDECLARE Value BIGINT;SELECT
AUTO_INCREMENT INTO Value
FROM
information_schema.tables
WHERE
table_name = TableName AND
table_schema =DATABASE();RETURN Value;END
usando en su consulta de inserción, para crear un Hash SHA1. ex.:
¿Esto siempre funciona? ¿Existe una condición de carrera si se realizan dos inserciones al mismo tiempo?
Jmons
0
Mejora de @ ravi404, en caso de que su compensación de autoincremento NO ES 1:
SELECT(`auto_increment`-1)+ IFNULL(@@auto_increment_offset,1)FROM INFORMATION_SCHEMA.TABLES
WHERE table_name = your_table_name
AND table_schema =DATABASE();
( auto_increment-1): db engine parece que siempre considera un desplazamiento de 1. Por lo tanto, debe deshacerse de esta suposición, luego agregar el valor opcional de @@ auto_increment_offset, o por defecto a 1: IFNULL (@@ auto_increment_offset, 1)
$auto_inc_db = mysql_query("SELECT * FROM my_table_name ORDER BY id ASC ");while($auto_inc_result = mysql_fetch_array($auto_inc_db)){$last_id =$auto_inc_result['id'];}$next_id =($last_id+1);
echo $next_id;//this is the new id,if auto increment ison
auto_increment
columnaRespuestas:
Úselo
LAST_INSERT_ID()
desde su consulta SQL.O
También puede usar
mysql_insert_id()
para obtenerlo usando PHP.fuente
LAST_INSERT_ID()
.mysqli_insert_id
Puedes usar
o si no desea utilizar information_schema, puede utilizar este
fuente
TABLES.AUTO_INCREMENT
se almacena en caché dev.mysql.com/doc/refman/8.0/en/… . El blog de Mysql también tiene varias publicaciones al respecto, pero la variable del sistema que mencionan parece obsoleta: mysqlserverteam.com/… mysqlserverteam.com/…Puede obtener el siguiente valor de incremento automático haciendo lo siguiente:
Tenga en cuenta que usted debe no usar esto para modificar la tabla, utilice una columna AUTO_INCREMENT de hacerlo de forma automática en su lugar.
El problema es que
last_insert_id()
es retrospectivo y, por tanto, se puede garantizar dentro de la conexión actual.Este bebé es prospectivo y, por lo tanto, no es único por conexión y no se puede confiar en él.
Solo en una base de datos de conexión única funcionaría, pero las bases de datos de conexión única de hoy tienen la costumbre de convertirse en bases de datos de conexión múltiple mañana.
Ver:
SHOW TABLE STATUS
fuente
insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'
?after insert
last_insert_id()
UPDATE
si tuviera también. Pero prefiero concatenar los dos en el momento de la visualización y ahorrar toda la molestia.SHOW TABLE STATUS
espera verdatabase name
despuésFROM
y'table name pattern'
despuésLIKE
.Esto devolverá el valor de incremento automático para la base de datos MySQL y no verifiqué con otras bases de datos. Tenga en cuenta que si está utilizando cualquier otra base de datos, la sintaxis de la consulta puede ser diferente.
fuente
La respuesta principal usa PHP MySQL_ para una solución, pensé que compartiría una solución PHP MySQLi_ actualizada para lograr esto. ¡No hay salida de error en este ejemplo!
Lanza el siguiente incremento automático que aparece en una tabla.
fuente
En PHP puedes probar esto:
O
fuente
Solución:
"DataBaseName" es el nombre de nuestra base de datos
fuente
Una consulta simple haría
SHOW TABLE STATUS LIKE 'table_name'
fuente
Puedes usar el disparador de mysql
fuente
payment_code
en elafter insert
disparador parece ser la mejor opción.No puede usar el ID mientras lo inserta, ni tampoco lo necesita. MySQL ni siquiera conoce el ID cuando inserta ese registro. Podrías simplemente guardar
"sahf4d2fdd45"
en lapayment_code
tabla y usarid
ypayment_code
más adelante.Si realmente necesita que su payment_code tenga la ID, ACTUALICE la fila después de la inserción para agregar la ID.
fuente
information_schema.tables
tabla.SELECT ... CONCAT(payment_code, id)
, o en su código de aplicación. Incluso puede envolver elSELECT
en aVIEW
, para que siempre devuelva el valor correcto, sin preocuparse por el CONCAT en cada SELECCIÓN de su aplicación.¿Para qué necesita el próximo ID incremental?
MySQL solo permite un campo de incremento automático por tabla y también debe ser la clave principal para garantizar la exclusividad.
Tenga en cuenta que cuando obtenga el siguiente ID de inserción, es posible que no esté disponible cuando lo use, ya que el valor que tiene está solo dentro del alcance de esa transacción. Por lo tanto, dependiendo de la carga en su base de datos, es posible que ese valor ya se haya utilizado para cuando llegue la siguiente solicitud.
Le sugiero que revise su diseño para asegurarse de que no necesita saber qué valor de incremento automático asignar a continuación
fuente
Sugiero que reconsidere lo que está haciendo. Nunca experimenté un solo caso de uso en el que se requiera ese conocimiento especial. La siguiente identificación es un detalle de implementación muy especial y no contaría con que sea seguro para ACID.
Haga una transacción simple que actualice su fila insertada con la última identificación:
fuente
Tiene que conectarse a MySQL y seleccionar una base de datos antes de poder hacer esto
fuente
utilice "mysql_insert_id ()". mysql_insert_id () actúa sobre la última consulta realizada, asegúrese de llamar a mysql_insert_id () inmediatamente después de la consulta que genera el valor.
A continuación se muestra el ejemplo de uso:
Espero que el ejemplo anterior sea útil.
fuente
Eso es :)
fuente
Aunque dudo de su productividad pero es 100% confiable
fuente
usando la respuesta de ravi404:
usando en su consulta de inserción, para crear un Hash SHA1. ex.:
fuente
Mejora de @ ravi404, en caso de que su compensación de autoincremento NO ES 1:
(
auto_increment
-1): db engine parece que siempre considera un desplazamiento de 1. Por lo tanto, debe deshacerse de esta suposición, luego agregar el valor opcional de @@ auto_increment_offset, o por defecto a 1: IFNULL (@@ auto_increment_offset, 1)fuente
Para mí funciona y parece simple:
fuente
$last_id
repetidamente cuando puedeDESC
. Tuwhile
bloque hizo un montón de trabajo inútil.Si no devuelve AUTO_INCREMENT correcto, inténtelo:
Esta caché clara para la tabla, en BD
fuente