Você quer o próximo id, ou o id da linha que você está inserindo atualmente? Ou seja, o id no final do código de pagamento deve ser o id da linha em que o código de pagamento está armazenado?
Mike de
id da linha que estou inserindo
faressoft
6
Nesse caso, concatene os valores ao recuperá-los, não ao inseri-los. É muito mais fácil assim, e você descarta obter o id errado ou ter que executar uma atualização - pense no que aconteceria se a linha que você acabou de inserir for solicitada por outro cliente, antes que a atualização tenha chance de ser executada: o cliente acabaria com um código de pagamento inválido. Em um sistema de baixo tráfego, isso pode não ocorrer, mas não vejo sentido em correr o risco.
Obrigado pelas duas primeiras opções .. Mas a terceira é apenas o número dois chamado de PHP .. Não tenho certeza o que torna isso mais rápido em grandes bancos de dados ...
Gerard ONeill
1
@GerardONeill Removido
ravi404 de
3
porque um cache é usado para recuperar os dados de information_schema.tables, esta solução não funciona mais para o mysql 8.
Você pode obter o próximo valor de incremento automático fazendo:
SHOW TABLE STATUS FROM tablename LIKE Auto_increment
/*or*/SELECT`auto_increment`FROM INFORMATION_SCHEMA.TABLES
WHERE table_name ='tablename'
Observe que você não deve usar isso para alterar a tabela, use uma coluna auto_increment para fazer isso automaticamente.
O problema é que last_insert_id()é retrospectivo e, portanto, pode ser garantido dentro da conexão atual.
Este bebê é prospectivo e, portanto, não é o único por conexão e não é confiável.
Isso funcionaria apenas em um único banco de dados de conexão, mas os bancos de dados de conexão única hoje têm o hábito de se tornarem bancos de dados de várias conexões amanhã.
Eu não votei contra ele, mas o problema de tentar usar o último valor de incremento automático é que ele pode não ser o último quando você começar a usá-lo - não importa a rapidez com que SELECT e o INSERT subsequente sejam realizados.
Mike de
@ Mike, e se for feito em uma única consulta? Algo assim insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'? Eu usaria a atualização no after insertgatilho e last_insert_id(), embora ...
binaryLV
1
@binaryLV: Quanto menor for a lacuna entre SELECT e INSERT, menor será a chance de que o valor tenha mudado, mas isso não exclui completamente. Imagine um sistema com milhares de acessos por minuto no banco de dados - as chances de o valor ter mudado aumentam drasticamente. O bloqueio de tabela ou linha pode impedir isso se for feito como uma única consulta, mas isso depende de um comportamento específico do mecanismo de banco de dados que pode não estar bem documentado. Eu iria com uma próxima UPDATEse eu também tivesse. Mas prefiro apenas concatenar os dois no momento da exibição e evitar todo o trabalho.
Mike de
3
SHOW TABLE STATUSespera ver database namedepois FROMe 'table name pattern'depois LIKE.
x-yuri
2
porque um cache é usado para recuperar os dados de information_schema.tables, esta solução não funciona mais para o mysql 8.
Bruno
15
Isso retornará o valor de incremento automático para o banco de dados MySQL e não verifiquei com outros bancos de dados. Observe que se você estiver usando qualquer outro banco de dados, a sintaxe da consulta pode 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();
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_name = 'your_table_name' e table_schema = 'your_database_name';
LJay
10
A resposta principal usa PHP MySQL_ para uma solução, pensei em compartilhar uma solução PHP MySQLi_ atualizada para conseguir isso. Não há saída de erro neste exemplo!
$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'];
Expulsa o próximo incremento automático que surge em uma tabela.
Tenha em mente que, com o primeiro método, se o registro com o id mais alto for eliminado, você criará um novo registro com o id que o id eliminado costumava ter.
Tom Jenkinson
e se a chave anterior foi usada em outras tabelas e ainda está lá, você pode acabar com uma magia muito estranha
Tebe
o primeiro retorna um id errado se você descartar o último registro inserido,
Ali Parsa
6
Solução:
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;
Atualizar payment_codeno after insertgatilho parece ser a melhor opção.
binaryLV de
3
Você não pode usar o ID durante a inserção, nem precisa dele. O MySQL nem sabe o ID quando você está inserindo esse registro. Você poderia apenas salvar "sahf4d2fdd45"na payment_codetabela e usar ide payment_codedepois.
Se você realmente precisa que seu código_de_pagamento tenha o ID nele, ATUALIZE a linha após a inserção para adicionar o ID.
+1 Para tornar isso um pouco mais explícito: se você pegar o valor 'mais recente' de uma coluna, só é garantido que será o valor mais recente no momento exato em que você o pegar. Pode não ser o valor mais recente quando você vier a usar esse valor em uma inserção subsequente. No caso de uma coluna de incremento automático, sempre há a chance de que outro valor tenha sido adicionado entre o momento em que você recuperou o id e o momento em que o inseriu em outro lugar. Se você está referenciando uma linha que acabou de inserir, usar LAST_INSERT_ID () é adequado. Se você está tentando garantir um valor exclusivo, não é.
Mike de
@cularis, o MySQL sabe o próximo id auto_increment, ele está listado na information_schema.tablestabela.
Johan
1
@faressoft: Se a ideia é ter um código de pagamento que compreende uma única string mais o id da linha que contém esse código de pagamento, basta combinar os dois quando você recuperar a linha - com um SELECT ... CONCAT(payment_code, id)ou no código do seu aplicativo. Você pode até envolver o SELECTem a VIEW, de forma que sempre retorne o valor correto, sem se preocupar com o CONCAT em cada SELECT do seu aplicativo.
Mike de
3
Para que você precisa do próximo ID incremental?
O MySQL permite apenas um campo de incremento automático por tabela e também deve ser a chave primária para garantir a exclusividade.
Observe que quando você obtém o próximo ID de inserção, ele pode não estar disponível ao usá-lo, pois o valor que você possui está apenas no escopo dessa transação. Portanto, dependendo da carga em seu banco de dados, esse valor já pode ser usado no momento em que a próxima solicitação chegar.
Eu sugeriria que você revise seu projeto para garantir que não precise saber qual valor de incremento automático atribuir a seguir
Não é uma boa ideia presumir o tipo de aplicativo que requer o ID. Existem aplicativos como o que estou trabalhando no momento que precisam do próximo ID incremental e o valor recuperado não corre o risco de ser alocado para outro script.
JG Estiot
3
Sugiro repensar o que você está fazendo. Nunca experimentei um único caso de uso em que esse conhecimento especial seja necessário. O próximo id é um detalhe de implementação muito especial e eu não contaria que ele fosse seguro para ACID.
Faça uma transação simples que atualize sua linha inserida com o último id:
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;
Posso contar um desses casos de uso, estou tentando diagnosticar um problema de produção, então preciso descobrir se a última linha de uma tabela é realmente a última linha ou se houve uma adicionada depois daquela que de alguma forma foi excluída, tabela tem um campo auto_increment nele, portanto, ao encontrar essas informações, posso concluir se a linha foi excluída ou nunca adicionada.
Usman
1
Isso pode funcionar para você, mas eu não confiaria nisso, pois não acho que você tenha qualquer garantia disso: dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html " quando a coluna AUTO_INCREMENT faz parte de um índice de várias colunas), os valores de AUTO_INCREMENT são reutilizados se você excluir a linha com o maior valor de AUTO_INCREMENT em qualquer grupo. "
Markus Malkusch
Obrigado, informações úteis, também de acordo com o auto_incremento do seu link compartilhado pode ser redefinido inserindo um número manualmente, então sim, não é confiável.
Usman
2
Você tem que se conectar ao MySQL e selecionar um banco de dados antes de fazer isso
$table_name ="myTable";$query = mysql_query("SHOW TABLE STATUS WHERE name='$table_name'");$row= mysql_fetch_array($query);$next_inc_value =$row["AUTO_INCREMENT"];
use "mysql_insert_id ()". mysql_insert_id () atua na última consulta realizada, certifique-se de chamar mysql_insert_id () imediatamente após a consulta que gera o valor.
Abaixo estão os exemplos 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());?>
Também concordo que esta é a abordagem mais simples. Não sei por que você foi votado contra, mas vou compensar com um voto positivo.
recurse
Eu não mencionei a necessidade de transação, se você não envolvê-lo dentro da transação, esse código é péssimo o mais rápido possível, ele encontra o carregamento real.
Tebe
1
E se a última linha foi excluída? Ou várias linhas mais recentes foram excluídas?
Liam W
Chaves liberadas sem emissão não são usadas a menos que você especifique explicitamente
Tebe
1
usando a resposta 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 em sua consulta de inserção, para criar um Hash SHA1. ex.:
Isso sempre funciona? Existe uma condição de corrida se duas inserções acontecerem ao mesmo tempo?
Jmons
0
Melhoria de @ ravi404, no caso de seu deslocamento de incremento automático NÃO SER 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): o motor db parece sempre considerar um deslocamento de 1. Portanto, você precisa descartar essa suposição e, em seguida, adicionar o valor opcional de @@ auto_increment_offset, ou padrão para 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
colunaRespostas:
Use
LAST_INSERT_ID()
da sua consulta SQL.Ou
Você também pode usar
mysql_insert_id()
para obtê-lo usando PHP.fonte
LAST_INSERT_ID()
.mysqli_insert_id
Você pode usar
ou se você não deseja usar information_schema você pode usar este
fonte
TABLES.AUTO_INCREMENT
está armazenado em dev.mysql.com/doc/refman/8.0/en/… . O blog do Mysql também tem várias postagens sobre isso, mas o sistema variável que eles mencionam parece desatualizado: mysqlserverteam.com/… mysqlserverteam.com/…Você pode obter o próximo valor de incremento automático fazendo:
Observe que você não deve usar isso para alterar a tabela, use uma coluna auto_increment para fazer isso automaticamente.
O problema é que
last_insert_id()
é retrospectivo e, portanto, pode ser garantido dentro da conexão atual.Este bebê é prospectivo e, portanto, não é o único por conexão e não é confiável.
Isso funcionaria apenas em um único banco de dados de conexão, mas os bancos de dados de conexão única hoje têm o hábito de se tornarem bancos de dados de várias conexões amanhã.
Vejo:
SHOW TABLE STATUS
fonte
insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'
? Eu usaria a atualização noafter insert
gatilho elast_insert_id()
, embora ...UPDATE
se eu também tivesse. Mas prefiro apenas concatenar os dois no momento da exibição e evitar todo o trabalho.SHOW TABLE STATUS
espera verdatabase name
depoisFROM
e'table name pattern'
depoisLIKE
.Isso retornará o valor de incremento automático para o banco de dados MySQL e não verifiquei com outros bancos de dados. Observe que se você estiver usando qualquer outro banco de dados, a sintaxe da consulta pode ser diferente.
fonte
A resposta principal usa PHP MySQL_ para uma solução, pensei em compartilhar uma solução PHP MySQLi_ atualizada para conseguir isso. Não há saída de erro neste exemplo!
Expulsa o próximo incremento automático que surge em uma tabela.
fonte
Em PHP, você pode tentar isso:
OU
fonte
Solução:
"DataBaseName" é o nome da nossa base de dados
fonte
Uma consulta simples faria
SHOW TABLE STATUS LIKE 'table_name'
fonte
Você pode usar o gatilho mysql
fonte
payment_code
noafter insert
gatilho parece ser a melhor opção.Você não pode usar o ID durante a inserção, nem precisa dele. O MySQL nem sabe o ID quando você está inserindo esse registro. Você poderia apenas salvar
"sahf4d2fdd45"
napayment_code
tabela e usarid
epayment_code
depois.Se você realmente precisa que seu código_de_pagamento tenha o ID nele, ATUALIZE a linha após a inserção para adicionar o ID.
fonte
information_schema.tables
tabela.SELECT ... CONCAT(payment_code, id)
ou no código do seu aplicativo. Você pode até envolver oSELECT
em aVIEW
, de forma que sempre retorne o valor correto, sem se preocupar com o CONCAT em cada SELECT do seu aplicativo.Para que você precisa do próximo ID incremental?
O MySQL permite apenas um campo de incremento automático por tabela e também deve ser a chave primária para garantir a exclusividade.
Observe que quando você obtém o próximo ID de inserção, ele pode não estar disponível ao usá-lo, pois o valor que você possui está apenas no escopo dessa transação. Portanto, dependendo da carga em seu banco de dados, esse valor já pode ser usado no momento em que a próxima solicitação chegar.
Eu sugeriria que você revise seu projeto para garantir que não precise saber qual valor de incremento automático atribuir a seguir
fonte
Sugiro repensar o que você está fazendo. Nunca experimentei um único caso de uso em que esse conhecimento especial seja necessário. O próximo id é um detalhe de implementação muito especial e eu não contaria que ele fosse seguro para ACID.
Faça uma transação simples que atualize sua linha inserida com o último id:
fonte
Você tem que se conectar ao MySQL e selecionar um banco de dados antes de fazer isso
fonte
use "mysql_insert_id ()". mysql_insert_id () atua na última consulta realizada, certifique-se de chamar mysql_insert_id () imediatamente após a consulta que gera o valor.
Abaixo estão os exemplos de uso:
Espero que o exemplo acima seja útil.
fonte
É isso aí :)
fonte
Embora eu duvide de sua produtividade, mas é 100% confiável
fonte
usando a resposta de ravi404:
usando em sua consulta de inserção, para criar um Hash SHA1. ex.:
fonte
Melhoria de @ ravi404, no caso de seu deslocamento de incremento automático NÃO SER 1:
(
auto_increment
-1): o motor db parece sempre considerar um deslocamento de 1. Portanto, você precisa descartar essa suposição e, em seguida, adicionar o valor opcional de @@ auto_increment_offset, ou padrão para 1: IFNULL (@@ auto_increment_offset, 1)fonte
Para mim funciona e parece simples:
fonte
$last_id
repetidamente quando você pode apenasDESC
. Seuwhile
bloco fez um monte de trabalho inútil.Se não retornar nenhum AUTO_INCREMENT correto, tente:
Este cache limpo para mesa, em BD
fonte