Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

mysql Ao duplicar valor no campo, insira nova linha com novo valor


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.