競合状態を適切に回避するにはLOCK TABLE
、およびトランザクションを使用して、一貫した結果を保証します。
あなたのクエリで
UPDATE items SET itemcode=CONCAT('XYZ',(SELECT COUNT(*) as ctr FROM items
WHERE itemcode!=''),'GZ') WHERE itemid=123;
特定のプロパティを持つレコードを選択していますitems
SELECT COUNT(*) as ctr FROM items WHERE itemcode!=''
次にitemcode
、itemid
123 の を XYZGZ に関連付けます。
これは、UPDATE JOIN
betweenitems
とで行うこともできますctr
:
UPDATE items JOIN (
SELECT CONCAT('XYZ', COUNT(*), 'GZ') AS newcode FROM items
WHERE itemcode!='') AS dummy
SET itemcode = dummy.newcode WHERE itemid = 123;
または、MySQL (および LOCK TABLES を使用) ではSELECT
、カウントを一時変数に入れ、itemcode
その変数に割り当てることができます。
mysql> CREATE TABLE items ( itemid integer, itemcode varchar(32) );
mysql> INSERT INTO items VALUES ( 1, 'one' ), ( 2, 'two' ), ( 123, 'and 123');
mysql> LOCK TABLE items WRITE;
mysql> BEGIN WORK;
mysql> SELECT COUNT(*) INTO @x FROM items WHERE itemcode != '';
mysql> UPDATE items SET itemcode=CONCAT('XYZ',@x,'GZ') WHERE itemid = 123;
mysql> COMMIT WORK;
mysql> UNLOCK TABLES;
mysql> SELECT * FROM items;
+--------+----------+
| itemid | itemcode |
+--------+----------+
| 1 | one |
| 2 | two |
| 123 | XYZ3GZ |
+--------+----------+
3 rows in set (0.00 sec)
明示的なロックなしで、同じことを行うより短い方法:
mysql> BEGIN WORK;
mysql> SELECT COUNT(*) INTO @x FROM items WHERE itemcode != '' FOR UPDATE;
mysql> UPDATE items SET itemcode=CONCAT('XYZ',@x,'GZ') WHERE itemid = 123;
mysql> COMMIT WORK;