MODIFICA:
Modificato dopo il commento dell'utente su questo post:
Hai bisogno di blocco della tabella di scrittura su entrambi questi due processi.
Un blocco WRITE ha le seguenti caratteristiche:
-
L'unica sessione che mantiene il blocco di una tabella può leggere e scrivere dati dalla tabella.
-
Le altre sessioni non possono leggere e scrivere dati nella tabella finché non viene rilasciato il blocco WRITE.
Guarda anche vincolo SQL UNIQUE
PRIMA DI MODIFICA:
Sì, è possibile. E mi ci è voluto un po' per capirlo. Lo costruisco sul tuo input e sui valori di confronto come test1, test2 ecc., Dove test è sempre lo stesso e ha un numero finale. Come hai specificato.
Può essere fatto come Transazione MySQL in 4 passaggi.
Diciamo che hai la tabella testT
dove il nome è unico per assicurarsi che non abbiamo doppi.
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
E vuoi inserire un nuovo elemento con il nome test1 che abbiamo impostato come:
SET @newName = 'test1';
Quindi dobbiamo verificare se esiste già nella tabella:
SELECT @check:=COUNT(*) FROM testT WHERE name = @newName;
Facciamo un conteggio qui per ottenere true o false e salvarlo come @check
qui così possiamo confrontarlo più tardi. Ciò risulterà in 1 row
come test1
esiste già nella tabella.
Quindi facciamo un'altra selezione per ottenere il numero più alto di test* e lo memorizziamo come @number
, questa query successiva seleziona tutti i test ed esegue una SUBSTRING dopo 4 secondi dandoci tutti i numeri dopo i primi 4 ultimi. (99999999999) numeri in realtà solo per essere sicuri di non perderne nessuno, ma nel nostro caso il risultato è solo "3" perché quello è l'ultimo record "test3
" nella tabella.
SELECT
@number:= SUBSTRING(name,5,99999999999)
FROM testT;
Ora possiamo fare un inserimento:
INSERT INTO testT(name)
VALUES
(
IF(@check = "", @newName , CONCAT(LEFT(@newName,4),RIGHT(@number,1)+1)
)
);
Questo prova a inserire il nostro @newName
nella tabella in condizione IF, e cioè se il nostro @check
è vuoto quindi inserirà @newName
, in caso contrario eliminerà il test di parole dalla stringa e aggiungerà un @number
più alto da prima e aggiungi anche + 1.
Quindi risultato per @newName = 'test1'
è sotto. Se lo modifichi in @newName = 'test3'
il risultato sarebbe lo stesso nuovo inserire 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 lo cambi in QUALSIASI test* quel numero non esiste già lo inserirà normalmente. Nel caso seguente:@newName = 'test6'
SET @newName = 'test6';
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test6 |
In questo modo verrà sempre eseguito un inserto.
Puoi giocare con questo qui:Visualizza su DB Fiddle
semplicemente cambiando SET @newName = 'test6'
Non sono un esperto e mi ci sono volute un paio d'ore per capire questa via d'uscita, poiché volevo sapere se fosse possibile. E apprezzerei se qualsiasi altro utente potesse suggerire qualsiasi altro modo o migliorare il mio metodo.