0
爲什麼在這段代碼中@changed是正確的,但@changed2是不正確的?目的是找出列值是否在更新語句中發生變化。我在這件事上沒有發現任何可以解釋這一點的細節。SQL Server UPDATE並同時設置變量操作順序
如果我不得不猜測,SQL Server將首先使用行的當前狀態更新設置變量,當它完成後它將實際更新它。這就是爲什麼@ changed2爲0,當解析@changed2變量時,VALUE列未被更新,所以我們必須使用@newValue。
IF Object_id('tempdb..#tmpTest') IS NOT NULL
DROP TABLE #tmptest;
CREATE TABLE #tmptest
(
test_id INT NOT NULL IDENTITY(1, 1),
value VARCHAR(20)
);
INSERT INTO #tmptest
(value)
VALUES ('hello');
然後運行該代碼多次(可以運行了好幾次,但不再次執行上述代碼!):
--then run this multiple times:
DECLARE @oldValue VARCHAR(20),
@newValue VARCHAR(20) = (SELECT value
FROM #tmptest
WHERE test_id = 1),
@changed BIT,
@changed2 BIT
--alternate values:
IF(@newValue = 'hello')
SET @newValue = 'goodbye'
ELSE
SET @newValue = 'hello'
--see current data
SELECT *
FROM #tmptest;
--update
UPDATE #tmptest
SET value = @newValue,
@oldValue = value,
@changed = CASE
WHEN @oldValue != @newValue THEN 1
ELSE 0
END,
@changed2 = CASE
WHEN @oldValue != value THEN 1
ELSE 0
END
WHERE test_id = 1;
--see changed data:
SELECT *
FROM #tmptest;
SELECT @oldValue oldValue,
@newValue newValue,
@changed changed,
@changed2 changed2
謝謝您的時間。
該代碼的結果實際上是未定義的;混合列分配與變量分配意味着所有的投注都關閉。搜索「古怪的更新」以獲取更多信息(以及爲什麼人們有時會使用這個)。 –
這是不正確的,甚至微軟推薦它在模擬SQL 2008 R2的序列時,像設置@NewSeqVal = CurrVal = CurrVal + Incr這裏鏈接:https://blogs.msdn.microsoft.com/sqlcat/2006/04/10/sql -server-sequence-number/ – Alex
好吧,我發現他們甚至[更新了文檔](https://msdn.microsoft.com/library/ms177523)來編譯這種更新形式。同樣的文檔也解釋了你所看到的:「SET @variable = column = expression'將變量設置爲與列相同的值,這不同於'SET @variable = column,column = expression',它設置變量到列的更新前的值。「 –