sql >> Database teknologi >  >> RDS >> Mysql

mysql Indsæt ny række med ny værdi i feltet Dupliker værdi

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.




  1. Enkel, men tung applikation, der kræver mange ressourcer. Hvordan optimerer man?

  2. MySQL Max-funktion blande rækker

  3. Overtrædelse af integritetsbegrænsning:1048 Kolonnen "taggable_id" kan ikke være null

  4. Brug af Spotlight Cloud til at løse SQL Server-blokering