2017-04-07 3 views
1

における単一の更新文で複数の列を更新するとき、私は更新クエリを持っている:更新シーケンスSQL

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

SQLは、順番に更新を行うのか?最初にCol6を更新してCol5などを更新しますか? Col3を最適化されたクエリプランで更新する前にCol2を更新する場合、Col3のCol1 /データを表示したくないです。もしそうなら、私は5つの列の更新ステートメントを別々に書く必要があります。あなたのDBの行にあなたが

col5 = 1 
col4 = 3 

あなたの更新を持っている場合は、これを生成します。

答えて

0

割り当てが発生しないDBの列に格納されている中、これまで値割り当てられた列の使用はnevevr上

は、例えば飛びます結果

一般に
col6 = 1 
col5= 3 
1

は、SQLの更新は、二つの異なる記録から来たものとしてsetの左右を扱います - レコードの「前」、右側にdは左側の「アフター」レコードです。実際には、ほとんどのデータベースはset句を順番に評価します(これが必要かどうかはわかりません)。

MySQLが異なります。これは、set句を順番に評価します。 割り当て後の列への参照は、古い値ではなく新しい値になります。これはdocumentationで説明されている:

次の文の2番目の割り当ては 電流(更新)COL1値ではなく、元のCOL1の値にCOL2を設定します。結果は で、col1とcol2の値は同じです。この動作は、 標準SQLとは異なります。

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

ので、書かれたとして、あなたの文は順番に評価されることが保証されています。すでに割り当てられた値を参照しているわけではないので、期待どおりに動作し、そのために文書化されています。

+0

ドキュメントでは、単一テーブルの更新は順番に行われますが、複数のテーブルの更新は行われない可能性があります。 更新T1 セットt1.Col6 = t1.Col5 、t1.Col5 = t1.Col4 、t1.Col4 = t1.Col3 、t1.Col3 = t1.Col2 、T1:だから、私の更新は、以下のようなものだった場合.Col2 = t1.Col1 、t1.Col1 = t2.Col0 from [table1] t1 t2.id = t1.id これは単一のテーブル更新または複数のテーブルとみなされますか? (私はそれが単一であると仮定している) – Abhishek

+0

@Abhishek。 。 。これは単一のテーブル構文です。しかし、その構文はMySQL構文ではなくSQL Serverの構文であることを強調する必要があります。この質問に間違いがある場合は、使用している実際のデータベースを明示的に指定する*別の質問をすることをお勧めします。 (この質問には、MySQLに基づいた4つの回答があり、データベースを変更するとそれらの回答は無効になります。) –

0

使用この形式:

UPDATE table-name 
    SET column-name = value, column-name = value, ... 
WHERE condition 
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,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は更新されませんでした。