UPDATE的同时操作特性 列的同时互换
原文地址:http://blog.sqlauthority.com/2008/10/20/sql-server-transaction-and-local-variables-swap-variables-update-all-at-once-concept/
本文受下面两篇文章的启发:
1) SQL SERVER – Effect of TRANSACTION on Local Variable – After ROLLBACK and After COMMIT
(http://blog.sqlauthority.com/2007/09/25/sql-server-effect-of-transaction-on-local-variable-after-rollback-and-after-commit/)
2) SQLAuthority News – Author Visit – SQL Hour at Patni Computer Systems
(http://blog.sqlauthority.com/2008/10/07/sqlauthority-news-author-visit-sql-hour-at-patni-computer-systems/)
我总是在文章最后作总结,但是本文我先作总结,然后再来解释。
事务对内存变量没有任何影响。当UPDATE字句更新某个表(物理表或者内存表),当事务提交时,所有的变换都是同一时间实现的。
首先,我假设你已经看过我上面列出的文章,关于事务对局部变量的影响。正如你看到的,局部变量不受任何事务的影响。
Example 1:PRINT 'After ROLLBACK example'
DECLARE @FlagINT INT
SET
@FlagInt = 1
PRINT @FlagInt ---- @FlagInt Value will be 1
BEGIN TRANSACTION
SET
@FlagInt = 2
PRINT @FlagInt ---- @FlagInt Value will be 2
ROLLBACK TRANSACTION
PRINT
@FlagInt ---- @FlagInt Value will be ?
GO
Example 2:PRINT 'After COMMIT example'
DECLARE @FlagINT INT
SET
@FlagInt = 1
PRINT @FlagInt ---- @FlagInt Value will be 1
BEGIN TRANSACTION
SET
@FlagInt = 2
PRINT @FlagInt ---- @FlagInt Value will be 2
COMMIT TRANSACTION
PRINT
@FlagInt ---- @FlagInt Value will be ?
GO
让我看看编程语言是如何交换变量。
比如我们有两个变量VarA和VarB,要交换这两个变量的值,我们只有借助于临时变量,代码流程如下:
TempVar = VarA;
VarA = VarB;
VarB = TempVar;
在SQL Server中,流程如下:
Example 3:DECLARE @VarA INT
DECLARE
@VarB INT
DECLARE
@VarTemp INT
SET @VarA = 1
SET @VarB = 2
SELECT @VarA VarA, @VarB VarB
SELECT @VarTemp = @VarA, @VarA = @VarB, @VarB = @VarTemp
SELECT @VarA VarA, @VarB VarB
GO
上面查询语句互换了变量值,结果显示如下:
看上面的两个例子,我们可能还看不出来他们有何联系。那么我们来看看本文的重点:在SQL中如何不使用变量来交换值。
现在,从例1中我们已经明白了:局部变量不受事务影响。从例3我们理解了在值交换的过程中临时变量的重要性。如果我们理解操作是如何完成的,我们可能就不再需要第三个变量了。
如果下面这两个操作同时发生的话,这时临时变量就可以省去了。
VarA = VarB; VarA = VarB;
让我们来看看下面将两列互换的例子。注意:我们没有使用临时列或者其它特殊的方法。两列只是通过给对方赋值来完成列交换的。
Example 4:
DECLARE @TableA TABLE
(Months VARCHAR(100), Days VARCHAR(100))
INSERT INTO @TableA (Months, Days)
SELECT 'Jan', 'Mon'
UNION
SELECT
'Feb', 'Tue'
UNION
SELECT
'Mar', 'Wed'
UNION
SELECT
'Apr', 'Thu'
UNION
SELECT
'May', 'Fri'
SELECT *
FROM @TableA
UPDATE @TableA
SET Months = Days,
Days = Months
SELECT *
FROM @TableA
GO
现在看看上面的查询:很清楚,UPDATE语句是同时更新两列,并且没有借助于临时列。这得归功于事务。当UPDATE语句执行时,它在内部交换了数据并且存储在内存中,当UPDATE事务提交时,它将新值(交换后的值)赋给列。
我想这可能就是UPDATE语句的事务特性。