sql >> データベース >  >> RDS >> Mysql

mysqlフィールドの値が重複している場合、新しい値で新しい行を挿入します

    編集:

    この投稿に対するユーザーのコメントの後に編集:

    書き込みテーブルロック が必要です これら2つのプロセスの両方で。

    書き込みロックには次の機能があります。

    • テーブルのロックを保持する唯一のセッションは、テーブルからのデータの読み取りと書き込みを行うことができます。

    • 他のセッションは、WRITEロックが解除されるまで、テーブルからデータを読み取ったり、テーブルにデータを書き込んだりすることはできません。

    SQLUNIQUE制約 もご覧ください。

    編集前:

    はい、可能です。そして、それを理解するのにしばらく時間がかかりました。これは、test1、test2などの入力値と競合する値に基づいて作成されます。ここで、testは常に同じで、末尾に番号が付いています。あなたが指定したように。

    これは、 MySQLTRANSACTION として実行できます。 4つのステップで。

    テーブルtestTがあるとしましょう ここで、名前はダブルがないことを保証するために一意です。

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

    そして、次のように設定したtest1という名前の新しいアイテムを挿入します。

    SET @newName = 'test1'; 
    

    次に、それがすでにテーブルに存在するかどうかを確認する必要があります:

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

    ここでカウントを行い、trueまたはfalseを取得して、@checkとして保存します。 ここで後で比較できます。これにより、1 rowになります test1として すでにテーブルに存在します。

    次に、別の選択を行って最大数のテスト*を取得し、それを@numberとして保存します。 、この次のクエリはすべてのテストを選択し、後者の4つの後にSUBSTRINGを実行して、後者の最初の4つの後にすべての数値を提供します。 (99999999999)数字は、実際には見逃さないようにするためのものですが、この場合、最後のレコード「test3」であるため、結果は「3」のみになります。 "テーブルに。

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

    これで挿入を実行できます:

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

    これは、@newNameを挿入しようとします IF条件でテーブルに追加します。これは、@checkの場合です。 空の場合、彼は@newNameを挿入します 、そうでない場合は、文字列から単語テストを取り出し、最高の@numberを追加します 以前から+1も追加します。

    したがって、@newName = 'test1'の結果 以下です。これを@newName = 'test3'に変更した場合 結果は同じ新しい挿入test4になります 。

    **Schema (MySQL v5.7)**
    
        SET @newName = 'test1';   
    
    ---
    
    **Query #1**
    
        SELECT * FROM testT
         ORDER BY id;
    
    | id  | name  |
    | --- | ----- |
    | 1   | test1 |
    | 2   | test3 |
    | 3   | test4 |
    
    ---
    

    また、任意のテスト*で変更した場合、その番号はまだ存在していませんが、通常どおり挿入されます。以下の場合:@newName = 'test6'

    SET @newName = 'test6';
        **Query #1**
    
            SELECT * FROM testT
             ORDER BY id;
    
        | id  | name  |
        | --- | ----- |
        | 1   | test1 |
        | 2   | test3 |
        | 3   | test6 |
    

    このようにして、常に挿入が行われます。

    ここでこれを試すことができます:DBFiddleで表示 SET @newName = 'test6'を変更するだけです

    私は専門家ではないので、これが可能かどうかを知りたかったので、この方法を理解するのに数時間かかりました。他のユーザーが他の方法を提案したり、私の方法を改善したりしていただければ幸いです。




    1. PostgreSQLで短い月の名前を取得する

    2. Django 500内部サーバーエラー-不適切に構成されています:MySQLdbモジュールの読み込み中にエラーが発生しました:

    3. ワークベンチを使用してpostgresqlデータベースをmysqlに移行しようとしたときにエラーが発生しました

    4. MySQLのselectクエリで正規表現を書く方法は?