[英]Can I insert (“squeeze in”) a row in a table and increase remaining values after the inserted row with one query in MySQL?
I wonder if I can insert a row in a table and increase all remaining values after the inserted row?我想知道我是否可以在表中插入一行并在插入的行之后增加所有剩余的值?
Take look at the sample table below:请看下面的示例表:
+----+----------+-----------+
| id | position | data |
+----+----------+-----------+
| 1 | 1 | Paris |
| 2 | 2 | London |
| 3 | 3 | Berlin |
| 4 | 4 | Madrid |
+----+----------+-----------+
The id
column is the primary key. id
列是主键。 The position
column is used to sort the data in custom order. position
列用于按自定义顺序对数据进行排序。 I now wonder if it's possible to create an INSERT/UPDATE-query in MySQL to "sqeeze in" a new city in the table, ie the position values need to be increased after the insert, like this:我现在想知道是否可以在 MySQL 中创建一个 INSERT/UPDATE-query 以“挤入”表中的一个新城市,即插入后需要增加 position 值,如下所示:
+----+----------+-----------+
| id | position | data |
+----+----------+-----------+
| 1 | 1 | Paris |
| 2 | 2 | London |
| 5 | 3 | New York | <-- inserted row... positions after are increased
| 3 | 4 | Berlin | <-- position +1
| 4 | 5 | Madrid | <-- position +1
+----+----------+-----------+
I first thought that I solve this in PHP by modifying each row in a loop.我首先想到我在 PHP 中通过修改循环中的每一行来解决这个问题。 But I hope I can solve this with one single INSERT-query.
但我希望我可以通过一个 INSERT 查询来解决这个问题。 Is that possible?
那可能吗?
INSERT INTO table SET position=3, data="New York" {AND INCREASE THE REST of postion}
Rows in tables are not physically stored in-order of their primary-key values (the real answer, as ever, is "it's complicated" - I'll be happy to go into detail on this point if you like).表中的行不是按其主键值的顺序物理存储的(与以往一样,真正的答案是“它很复杂” - 如果您愿意,我很乐意在这一点上详细介绍 go)。
But w.r.t.但是 w.r.t。 your question, the solution is straightforward:
你的问题,解决方案很简单:
SET @insertAtPosition = 3;
SET @insertData = 'New York';
BEGIN TRANSACTION;
UPDATE tbl SET Position = Position + 1 WHERE Position >= @insertAtPosition;
INSERT INTO tbl ( Position, Data ) VALUES ( @insertAtPosition, @insertData );
COMMIT TRANSACTION;
Note that the use of BEGIN TRANSACTION
and COMMIT TRANSACTION
is important so that the Position
values won't be updated without a new row being successfully inserted - if the INSERT
(or the UPDATE
) fails for whatever reason, then the Position
values will be unchanged, as though the attempt was never made.请注意,使用
BEGIN TRANSACTION
和COMMIT TRANSACTION
很重要,这样Position
值不会在没有成功插入新行的情况下更新 - 如果INSERT
(或UPDATE
)由于任何原因失败,则Position
值将保持不变,就好像从未进行过尝试一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.