Mysql
 sql >> Base de données >  >> RDS >> Mysql

mysql Sur la valeur en double dans le champ, insérez une nouvelle ligne avec une nouvelle valeur

MODIF :

Modifié après le commentaire de l'utilisateur sur ce message :

Vous avez besoin de verrouiller la table d'écriture sur ces deux processus.

Un verrou WRITE a les caractéristiques suivantes :

  • La seule session qui détient le verrou d'une table peut lire et écrire des données à partir de la table.

  • Les autres sessions ne peuvent pas lire et écrire des données dans la table tant que le verrou WRITE n'est pas libéré.

Regardez aussi SQL UNIQUE Constraint

AVANT LA MODIFICATION :

Oui c'est possible. Et j'ai mis du temps à comprendre. Je construis cela sur vos valeurs d'entrée et de comparaison comme test1, test2, etc., où test est toujours le même et a un numéro de fin. Comme vous l'avez précisé.

Cela peut être fait comme MySQL TRANSACTION en 4 étapes.

Disons que vous avez la table testT où le nom est unique pour s'assurer que nous n'avons pas de doubles.

| id  | name  |
| --- | ----- |
| 1   | test1 |
| 2   | test3 |

Et vous voulez insérer un nouvel élément avec le nom test1 que nous définissons comme :

SET @newName = 'test1'; 

Ensuite, nous devons vérifier s'il existe déjà dans le tableau :

SELECT @check:=COUNT(*) FROM testT WHERE name = @newName;    

Nous comptons ici pour obtenir vrai ou faux et l'enregistrons sous @check ici pour que nous puissions le comparer plus tard. Cela se traduira par 1 row comme test1 existe déjà dans la table.

Ensuite, nous faisons une autre sélection pour obtenir le plus grand nombre de tests* et le stockons sous @number , cette requête suivante sélectionne tous les tests et fait un SUBSTRING après 4 derniers nous donnant tous les nombres après les 4 premiers derniers. (99999999999) nombres en fait juste pour être sûr de n'en manquer aucun mais dans notre cas le résultat n'est que "3" car c'est le dernier enregistrement "test3 " dans le tableau.

SELECT 
    @number:= SUBSTRING(name,5,99999999999) 
FROM testT; 

Nous pouvons maintenant faire une insertion :

INSERT INTO testT(name)
VALUES
(
    IF(@check = "", @newName , CONCAT(LEFT(@newName,4),RIGHT(@number,1)+1)
)
);

Ceci essaie d'insérer notre @newName dans la table sous condition IF, et c'est si notre @check est vide alors il insérera @newName , sinon, il prendra le test de mot hors de la chaîne et ajoutera un @number le plus élevé de plus tôt et ajoutez + 1 aussi.

Donc résultat pour @newName = 'test1' est inférieure à. Si vous changez cela en @newName = 'test3' le résultat sera le même nouveau insert test4 .

**Schema (MySQL v5.7)**

    SET @newName = 'test1';   

---

**Query #1**

    SELECT * FROM testT
     ORDER BY id;

| id  | name  |
| --- | ----- |
| 1   | test1 |
| 2   | test3 |
| 3   | test4 |

---

Et si vous le modifiez dans N'IMPORTE QUEL test*, ce numéro n'existe pas déjà, il l'insérera normalement. Dans le cas ci-dessous :@newName = 'test6'

SET @newName = 'test6';
    **Query #1**

        SELECT * FROM testT
         ORDER BY id;

    | id  | name  |
    | --- | ----- |
    | 1   | test1 |
    | 2   | test3 |
    | 3   | test6 |

De cette façon, un insert sera toujours réalisé.

Vous pouvez jouer avec ça ici :Voir sur DB Fiddle juste en changeant SET @newName = 'test6'

Je ne suis pas un expert et il m'a fallu quelques heures pour comprendre cette solution, car je voulais savoir si cela était même possible. Et j'apprécierais si un autre utilisateur pouvait suggérer une autre manière ou améliorer ma méthode.