在SQL中的单个更新语句中更新多个列时更新序列

时间:2017-04-07 19:29:16

标签: mysql

我有更新查询:

update  t
set     Col6=Col5
    ,   Col5=Col4
    ,   Col4=Col3
    ,   Col3=Col2
    ,   Col2=Col1
from    [table] t

sql是否按顺序执行更新?首先更新Col6,然后更新Col5,依此类推? 我不想在Col3中看到Col1数字/数据,以防sql在通过某种优化的查询计划更新Col3之前更新Col2。如果是这样,我将分别写出所有5列更新语句。

4 个答案:

答案 0 :(得分:1)

通常,SQL更新将set的左侧和右侧视为来自两个不同的记录 - 右侧的“之前”记录和左侧的“之后”记录。在实践中,大多数数据库按顺序评估set子句(我不确定这是否是必需的)。

MySQL与众不同。它按顺序评估set子句。分配后对列的引用是新值,而不是旧值。这在documentation

中有解释
  

以下语句中的第二个赋值将col2设置为   当前(更新)col1值,而不是原始col1值。结果   是col1和col2具有相同的值。这种行为不同于   标准SQL。

UPDATE t1 SET col1 = col1 + 1, col2 = col1;

因此,保证按顺序评估您的书面陈述。因为您没有引用已经分配的值,所以它可以按预期工作,并且可以记录这些值。

答案 1 :(得分:0)

分配的列使用了存储在db行中的值,赋值不会在飞行中发生nevevr

例如:如果你的db行中有

 col5 = 1
 col4 = 3

您的更新产生此结果

 col6 = 1
 col5=  3

答案 2 :(得分:0)

使用以下格式:

UPDATE table-name 
   SET column-name = value, column-name = value, ...
 WHERE condition

答案 3 :(得分:0)

您的查询不包含where子句,因此,每行都将更新。大多数关系引擎通过维护旧值和新值来工作(调查触发器以获取有关此概念的更多信息)。您创建的查询是将存储在一列中的旧值分配给另一列的新值。

create table test (col1 int, col2 int, col3 int, col4 int, col5 int, col6 int);
insert into test values (1,2,3,4,5,6), (10,20,30,40,50,60);
commit;

select * from test;
+------+------+------+------+------+------+
| col1 | col2 | col3 | col4 | col5 | col6 |
------+------+------+------+------+------+
|    1 |    2 |    3 |    4 |    5 |    6 |
|   10 |   20 |   30 |   40 |   50 |   60 |
+------+------+------+------+------+------+
2 rows in set (0.00 sec)

update  test
set Col6=Col5
,   Col5=Col4
,   Col4=Col3
,   Col3=Col2
,   Col2=Col1;
commit;

select * from test;
+------+------+------+------+------+------+
| col1 | col2 | col3 | col4 | col5 | col6 |
+------+------+------+------+------+------+
|    1 |    1 |    2 |    3 |    4 |    5 |
|   10 |   10 |   20 |   30 |   40 |   50 |
+------+------+------+------+------+------+
2 rows in set (0.00 sec)

如上所述,col6包含5,5中4中的内容,依此类推。 Col1保留原始值,因为它未重新定义。

那么如果我们尝试引用更改后的值会发生什么?

update  test
set Col1=Col2
,   Col2=Col3
,   Col3=Col4
,   Col4=Col5
,   Col5=Col6;
commit;

select * from test;
+------+------+------+------+------+------+
| col1 | col2 | col3 | col4 | col5 | col6 |
+------+------+------+------+------+------+
|    1 |    2 |    3 |    4 |    5 |    5 |
|   10 |   20 |   30 |   40 |   50 |   50 |
+------+------+------+------+------+------+
2 rows in set (0.00 sec)

如您所见,MySQL按预期将相应的值分配给列。 Col6未更新,因为未定义新值。