EDIT:
Redigeret efter brugerkommentar til dette indlæg:
Du skal bruge skrivetabellåsning på begge disse to processer.
En WRITE-lås har følgende funktioner:
-
Den eneste session, der holder låsen af en tabel, kan læse og skrive data fra tabellen.
-
Andre sessioner kan ikke læse data fra og skrive data til tabellen, før WRITE-låsen er frigivet.
Se også SQL UNIQUE Constraint
FØR REDIGERING:
Ja det er muligt. Og det tog mig et stykke tid at finde ud af det. Jeg bygger dette på dine input- og kompareringsværdier som test1, test2 osv., hvor testen altid er den samme og har et efterfølgende nummer. Som du specificerede.
Det kan gøres som MySQL TRANSACTION i 4 trin.
Lad os sige, at du har tabellen testT
hvor navnet er unikt for at sikre, at vi ikke har nogen doubler.
| id | navn || --- | ----- || 1 | test1 || 2 | test3 |
Og du vil indsætte et nyt element med navnet test1, vi indstiller til:
SET @newName ='test1';
Så skal vi tjekke om det allerede findes i tabel:
SELECT @check:=COUNT(*) FROM testT WHERE name =@newName;
Vi tæller her for at få sandt eller falsk og gemmer det som @check
her, så vi kan sammenligne det senere. Dette vil resultere i 1 række
som test1
findes allerede i tabellen.
Dernæst foretager vi endnu et valg for at få det højeste antal test* og gemmer det som @number
, denne næste forespørgsel udvælger alle test og laver en SUBSTRING efter 4 sidstnævnte giver os alle tal efter de første 4 sidstnævnte. (99999999999) tal faktisk bare for at være sikker på, at vi ikke går glip af nogen, men i vores tilfælde er resultatet kun "3", fordi det er sidste post "test3
" i tabellen.
SELECT @nummer:=SUBSTRING(navn,5,99999999999) FRA testT;
Nu kan vi lave en indsættelse:
INSERT INTO testT(name)VALUES( IF(@check ="", @newName , CONCAT(LEFT(@newName,4),RIGHT(@number,1)+1)));
Dette forsøger at indsætte vores @newName
ind i tabellen under IF-tilstand, og det er hvis vores @check
er tom, så vil han indsætte @newName
, hvis ikke, vil det tage ordtest ud af strengen og tilføje et højeste @nummer
fra tidligere og tilføj + 1 til det.
Så resultatet for @newName ='test1'
er nedenfor. Hvis du ændrer dette til @newName ='test3'
resultat ville være det samme nye indsæt test4
.
**Skema (MySQL v5.7)** SET @newName ='test1'; ---**Forespørgsel #1** VÆLG * FRA testT BESTIL EFTER id;| id | navn || --- | ----- || 1 | test1 || 2 | test3 || 3 | test4 |---
Og hvis du ændrer det i ENHVER test*, eksisterer det nummer ikke allerede, vil det indsætte det normalt. I tilfældet nedenfor:@newName ='test6'
SET @newName ='test6'; **Forespørgsel #1** VÆLG * FRA testT BESTIL EFTER id; | id | navn | | --- | ----- | | 1 | test1 | | 2 | test3 | | 3 | test6 |
På denne måde vil der altid blive lavet en indsats.
Du kan lege med dette her :Se på DB Fiddle
bare ved at ændre SET @newName ='test6'
Jeg er ingen ekspert, og det tog mig et par timer at finde ud af denne vej, da jeg ville vide, om dette overhovedet var muligt. Og jeg ville sætte pris på, hvis en anden bruger kan foreslå en anden måde eller forbedre min metode.