你會用微軟sql server的Update語句的一個擴展功能,還有如何繞過它的一個bug(首發)嗎?


微軟Sql server的Update語句,有個不錯的擴展功能,通過允許變量賦值,可在語句中嵌入復雜的邏輯計算,從而讓本來需要一個Select 加一個Update語句的段子,被優化成只需一個update語句。這對性能提高有不小的好處.但是,這項功能有個尚未報告且不易注意的bug.

舉例來說,下述形式都是合法的:

Update table1 set column1 = expr1, @var1 = expr2, @var2= column2 = expr3, ...  where where_condition

 

為了說更透徹的說明問題, 看下面的語句:

UPDATE dbo.TableX
 SET @oldDesc = Description, @OldApr = ApproveBits, 
  @NewApr = case when @OldApr & @txtCheck <> 0 and @oldDesc <> @Description then @OldApr & @txtMask2 
    else @OldApr end, 
  @NewApr = (case when @NewApr & @rateCheck = 0 then @NewApr 
   when @protectlevel >= XRate then @NewApr | @rateBit
   else @NewApr & @rateMask end),
  ApproveBits = @NewApr, --don't as @NewApr=ApproveBits= 
-- parse incorrectly due to a bug
  @dateSet = case when LastModified is null and (@NewApr = 0 or @NewApr = 3) then 1 else 0 end, 
  LastModified = case when @dateSet = 1 then @pnewDate else LastModified end,...
 WHERE ...

 

 

你看了上面的代碼會不會暈?. 在Update Clause中, 標准的sql只允許對數據庫表的列賦值.由於微軟sql的這一擴展, 允許對變量賦值, 再和case 語句組合起來, 就可以實現相當復雜的邏輯計算.如果沒有這些,一個Update語句就能做完的事情,就需要一個Select加一個Update語句才能實現.上面的那個例子,全面的利用了這一功能,從而實現對性能的提高和優化.

 

你如果看到上面的代碼會暈,那是因為,微軟本身提供的文檔並沒有完整透徹的說明這一功能,經過我個人的測試和總結,補充以下重要條款:

1.由於允許被賦值的是變量,可以在update中嵌入復雜的邏輯計算,並且可以讓本來需要一個select 加一個update語句的段子,被優化成只需要一個update語句的段子。這對性能提高有不小的好處。

2。@var2= column2 = expr3, 等同於: @var2= expr3, column2 = expr3

不同於“@var2= column2, column2 = expr3" 或者“column2 = expr3, @var2= column2", 后兩種形式都是把column2的舊值賦予了@var2.

3. 形式: column2 = @var2= expr3, 非法.

由於可能出現嵌套引用,所以必須知道在賦值時的優先級,規則如下,

4. 變量賦值相對列賦值優先.

5. 如果都是變量賦值,那么更靠左邊的優先.

6. 在賦值表達式右邊出現的變量的值是該變量的當前值.

7. 在賦值表達式右邊出現的列的值永遠是該列的舊值, 與在update語句中的次序無關.

 

目前, 這個擴展功能有一個bug, 就是,在下面的形式中:

"...set @var2 = expr1, @var2= column2 = expr2,... ",

你會想當然地認為@var2最后的值是expr2, 但是,由於這個bug,實際上, var2最后的值是expr1.

為了繞開這個bug, 你可以把上面重寫成下面的形式:

@var2 = expr1, @var2= expr2, column2 = @var2

 

這里介紹的都是個人精煉的,在微軟的文獻中找不到的,值得收藏呵.

weibo:JohnXhark


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM