EDITAR:
Editado após o comentário do usuário nesta postagem:
Você precisa de escrever bloqueio de tabela em ambos os dois processos.
Um bloqueio WRITE possui os seguintes recursos:
-
A única sessão que mantém o bloqueio de uma tabela pode ler e gravar dados da tabela.
-
Outras sessões não podem ler e gravar dados na tabela até que o bloqueio WRITE seja liberado.
Veja também SQL UNIQUE Constraint
ANTES DA EDIÇÃO:
Sim, é possível. E demorei um pouco para descobrir. Eu construo isso em sua entrada e valores como test1, test2 etc, onde test é sempre o mesmo e tem um número final. Como você especificou.
Isso pode ser feito como MySQL TRANSACTION em 4 passos.
Digamos que você tenha a tabela
testT
onde o nome é único para garantir que não haja duplos. | id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
E você deseja inserir um novo item com o nome test1 que definimos como:
SET @newName = 'test1';
Então precisamos verificar se já existe na tabela:
SELECT @check:=COUNT(*) FROM testT WHERE name = @newName;
Fazemos uma contagem aqui para obter verdadeiro ou falso e salvamos como
@check
aqui para que possamos compará-lo mais tarde. Isso resultará em 1 row
como test1
já existe na tabela. Em seguida, fazemos outra seleção para obter o maior número de testes* e armazená-lo como
@number
, esta próxima consulta seleciona todos os testes e faz uma SUBSTRING após 4 últimos dando-nos todos os números após os primeiros 4 últimos. (99999999999) números na verdade apenas para ter certeza de que não perdemos nenhum, mas no nosso caso o resultado é apenas "3" porque esse é o último registro "test3
" na tabela. SELECT
@number:= SUBSTRING(name,5,99999999999)
FROM testT;
Agora podemos fazer uma inserção:
INSERT INTO testT(name)
VALUES
(
IF(@check = "", @newName , CONCAT(LEFT(@newName,4),RIGHT(@number,1)+1)
)
);
Isso tenta inserir nosso
@newName
na tabela sob a condição IF, e isso é se nosso @check
estiver vazio então ele irá inserir @newName
, caso contrário, ele tirará o teste de palavras da string e acrescentará um @number
mais alto de antes e adicione + 1 também. Então resultado para
@newName = 'test1'
está abaixo. Se você alterar isso para @newName = 'test3'
resultado seria a mesma nova inserção test4
. **Schema (MySQL v5.7)**
SET @newName = 'test1';
---
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test4 |
---
E se você alterá-lo em QUALQUER teste* esse número ainda não existe ele irá inseri-lo normalmente. No caso abaixo:
@newName = 'test6'
SET @newName = 'test6';
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test6 |
Desta forma será sempre feita uma inserção.
Você pode brincar com isso aqui:Ver no DB Fiddle apenas alterando
SET @newName = 'test6'
Eu não sou especialista e levei algumas horas para descobrir essa maneira, pois eu queria saber se isso era possível. E eu agradeceria se algum outro usuário pudesse sugerir outra maneira ou melhorar meu método.