今天同仁問了一個問題,他用字串動態組了一個超長的語法,但該字串列出來時發現中間少了一些語法,似乎是字串相加時被截掉了。
因此我花了一些時間研究一下字串相加時型態轉換問題,這邊說的字串是指沒有明確宣告變數直接在TSQL中 'my name is ' + 'rock'用單引號括起來的字串。
其中發現當一個7000字的字串跟另一個7000自字串相加會是14000字的字串嗎?
答案是否定的 : 一個 '……7000字' + '……7000字' 的結果會產出一個 '…..8000字' 的字串。
但是一個 '……9000字' + '……7000字' 的結果卻會產出一個 '…..16000字' 的字串。
WHY?
因為 '……7000字' 由於字串字數低於8000,在SQL中會被視為是varchar型態,所以有8000個字的上限。因此 varchar(8000) + varchar(8000) 其結果自然還是 varchar(8000) ,所以超過8000的字會被截掉。
然而 '……9000字' 由於字數超過8000,在SQL中會被視為是varchar(max)型態,因此 varchar(max) + varchar(8000) 其結果會轉成 varchar(max),因此 '……9000字' + '……7000字' 才會產出 '…..16000字' 的字串。
當varchar跟nvarchar字串相加呢?
根據SQL資料類型優先順序,nvarchar是優先於varchar的,因此兩個型態相加會將varchar轉成nvarchar後再組合字串。
當剛剛上述字串相加又遇見是 varchar + nvarchar 時會產生另一奇特狀況
例如 '……7000字' + N'……7000字' 時,'……7000字' 型態會是varchar,而N'……7000字'因為字串前加N表示他是nvarchar型態,且該字串是7000個字超過nvarchar 4000個字的上限,因此會被隱轉成nvarchar(max)。
所以 '……7000字' + N'……7000字' 會是 varchar(8000) + nvarchar(max)。此時請注意 varchar 需轉成nvarchar才能相加,因此會變成是 nvarchar(4000) + nvarchar(max),varchar(8000) 變 nvarchar(4000),所以該字串會被從7000截斷成4000後再跟nvarchar(max)相串,因此 '……7000字' + N'……7000字' 會產出 '…..11000字' 的字串。
而ROCK的同事就是遇見上面這樣的問題導致字串被截斷,而幫他的解法就只是明確讓SQL用相同型態來串字串來避免這樣的問題。
我是ROCK
rockchang@mails.fju.edu.tw