編集:
この投稿に対するユーザーのコメントの後に編集:
書き込みテーブルロック が必要です これら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'
を変更するだけです
私は専門家ではないので、これが可能かどうかを知りたかったので、この方法を理解するのに数時間かかりました。他のユーザーが他の方法を提案したり、私の方法を改善したりしていただければ幸いです。