天天看點

字元串的長度,是字元數量,還是位元組數量?

對于大多數SQL Server程式設計開發者來說,當計算字元串的長度時,腦海中閃現的第一個函數是:Len(string),這個“長度”,預設情況下,是指字元的數量,一個英語字元是一個長度,一個漢字是一個長度。大多數的字元串函數,例如charindex,substring,stuff等函數,其位置都是針對字元數量的,這使得Len函數深入人心,但是,一個Unicode字元,占用的位元組數量是2Byte,而一個普通的ASCII字元占用的位元組數量是1Byte,當需要計算字元串占用的位元組數量時,要如何計算?對于各個類型所占用的位元組數量,又該如何計算?帶着這個疑問,讓我們一睹DataLength函數的廬山真面目。

一,字元數量

Len(string) 函數傳回的數值是字元的數量(number of characters),在統計字元數量時,不包含結尾空格,但是包含前導空格。

示例,Len 函數傳回的是字元的數量,而不是字元的位元組數量。

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。

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,是以字元數量來計算起始位置和長度。

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.

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:

String Functions (Transact-SQL)

LEN (Transact-SQL)

DATALENGTH (Transact-SQL)

作者

:悅光陰

出處

:http://www.cnblogs.com/ljhdo/

本文版權歸作者和部落格園所有,歡迎轉載,但未經作者同意,必須保留此段聲明,且在文章頁面醒目位置顯示原文連接配接,否則保留追究法律責任的權利。