【SQL】小心字符串拼接導致長度爆表


請看代碼:

DECLARE @max VARCHAR(max) SET @max='aaa...' --這里有8000個a
         +'bb' --連接一個varchar常量或變量

SELECT LEN(@max)

別想當然以為它會返回8002,而是8000,select @max也只會得到8000個a,后面兩個b沒了。我們知道,varchar(max)類型不受字符數限制,但為什么會這樣?

這其實與@max的數據類型無關,而是與字符串拼接后得到的數據類型有關,或者說,與字符串常量的數據類型推斷有關。在SQL 2005和SQL 2008(R2)中,敲一個'a',系統會把它作為varchar(1),'aa'則是varchar(2),N'a'則是nvarchar(1),而'a...'(超過8000個a)呢,05中會當它是text,08則當它是varchar(max),常量或變量的數據類型可以通過系統函數SQL_VARIANT_PROPERTY獲取,使用示例:

SELECT SQL_VARIANT_PROPERTY('a','BaseType')

有關該函數的更多信息請參看SSMS幫助或http://technet.microsoft.com/zh-cn/library/ms178550(v=sql.105).aspx

那么問題來了,既然超過8000個字符的常量系統會自動識別為大數據類型,不會出現截斷,為什么拼接一下就歇菜了,這是因為varchar(n)+varchar(n)還是=varchar(n),拼接時系統會自動拓展數據長度,但不會更改數據類型(varchar(n)與varchar(max)應視為不同數據類型),又因為varchar(n)中的n最大取值為8000,所以varchar(x)+varchar(y)最大只會得到varchar(8000),當x+y>8000時,便會出現截斷。

回到文章開頭的例子,就很明了了,'aaa...'和'bb'都是varchar(n),拼接后得到varchar(8000),也就是截斷了的8000個'aaa...',所以即便把它賦值給varchar(max)也無濟於事。如果'aaa...'再多個a,情況又不同了,這時就是text或varchar(max)+varchar(n),對於05,會報text與varchar不能拼接,對於08,會正確得到無截斷的'aaa...bb',因為varchar(max)+varchar(n)=varchar(max)。

OK就到這里,希望猿友在拼接SQL字串時留意這個問題。


免責聲明!

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



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