對於大多數SQL Server程式設計開發者來說,當計算字串的長度時,腦海中閃現的第一個函式是:Len(string),這個“長度”,預設情況下,是指字元的數量,一個英語字元是一個長度,一個漢字是一個長度。大多數的字串函式,例如charindex,substring,stuff等函式,其位置都是針對字元數量的,這使得Len函式深入人心,但是,一個Unicode字元,佔用的位元組數量是2Bytes,而一個普通的ASCII字元佔用的位元組數量是1Byte,當需要計算字串佔用的位元組數量時,要如何計算字串的長度?對於各個型別所佔用的位元組數量,又該如何計算?帶著這個疑問,讓我們一睹DataLength函式的廬山真面目。
一,字元數量
Len(string) 函式返回的數值是字元的數量(number of characters),在統計字元數量時,不包含結尾空格,但是包含前導空格。
示例,Len 函式返回的是字元的數量,而不是字元的位元組數量。
1 2 3 4 5 6 7 8 9 10 |
declare @str_v varchar(10) declare @str_nv nvarchar(10) declare @str_nv_cn nvarchar(10) set @str_v=' ab ' set @str_nv=N' ab ' set @str_nv_cn=N' 悅光陰' select len(@str_v) as len_v ,len(@str_nv) as len_nv , len(@str_nv_cn) as str_nv_cn |
二,位元組數量
對於varchar型別,大家都知道,這是單位元組字元,一個字元佔用一個位元組,總共能夠表示的256個字元;而對於nvarchar型別,一個字元佔用兩個位元組,能夠表示世界上所有的字符集,一個unicode字元佔用兩個位元組,如果要計算字串佔用的位元組數量(number of bytes),請使用DataLength()函式,該函式統計位元組數量時,字串的所有字元都會計算在內,包括前導空格和結尾空格。
示例,每個unicode字元佔2B,ASCII 字元佔1B。
1 2 3 4 5 6 7 8 9 10 |
declare @str_v varchar(10) declare @str_nv nvarchar(10) declare @str_nv_cn nvarchar(10) set @str_v=' ab ' set @str_nv=N' ab ' set @str_nv_cn=N' 悅光陰' select datalength(@str_v) as len_v ,datalength(@str_nv) as len_nv , datalength(@str_nv_cn) as str_nv_cn |
三,依賴字元數量的函式
對於字串函式:left,right,其長度值是指字元的數量;對於含有位置引數的字串函式,charindex、stuff 和 substring,是以字元數量來計算起始位置和長度。
1 2 3 4 |
STUFF ( character_expression , start , length , replaceWith_expression ) SUBSTRING ( expression ,start , length ) RIGHT ( character_expression , length ) LEFT ( character_expression , length ) |
四,檢視資料型別(Data Type)所佔用的儲存空間
DataLength()函式能過返回任意資料型別的變數所佔用的位元組數量,在設計表的schema時,為column定義窄的資料型別,在儲存海量資料行時,該函式十分有用。
例如,對於datetime型別佔用固定的8B,DateTime2資料型別儲存日期和時間,佔用的儲存空間不固定。根據儲存的時間部分 fractional seconds precision來確定DateTime2的Storage Size,6 bytes for precisions less than 3; 7 bytes for precisions 3 and 4. All other precisions require 8 bytes.
1 2 3 4 5 6 7 8 9 |
declare @dt1 datetime declare @dt2 datetime2(2) declare @dt3 datetime2(4) set @dt1=getdate() set @dt2=getdate() set @dt3=SYSDATETIME() select DATALENGTH(@dt1),DATALENGTH(@dt2),DATALENGTH(@dt3),@dt1,@dt2,@dt3 |
如果對time的精度(Precision)要求不是很高,保留2位毫秒,使用datetime2(2),比其他型別節省儲存空間。
參考doc: