1. 問題描述
在同步數據時常常會發現一個錯誤:將截斷字符串或二進制數據。
2. 問題原因
這個問題出現的原因是:要插入的數值字段的長度超出了數據庫中字段的長度。比如:插入的字符串字節長度是40,數據庫中字段長度設置為了varchar(36)就會報此錯誤。
3.問題擴展
a. 如何計算字符串長度和字節長度,既:datalength和len區別。
len:返回字符串的長度
datalength:返回字符串的字節長度
select len(convert(varchar(50),N'獅lion')) --5 N''表示Unicode格式字符串
select datalength(convert(varchar(50),N'獅lion')) --6
select len(N'獅lion') --5
select datalength(N'獅lion') --10
接下來我們分析一下為何會這樣.
len返回字符串的字符長度,既:一個漢字'獅'+4個字母'lion'=5個字符。每個漢字和字母都占一個字符長度。
datalength返回字符串的字節長度。對於字節長度,需要理解:一般編碼模式下,漢字和英文字母所占字節是不一樣的。一般來說,漢字占2個字節,英文字符占一個字節。而對於Unicode編碼,漢字和英文字母都占2個字節。
講解一下varchar和nvarchar的區別,varchar是普通編碼的字符串,nvarchar是Unicode編碼的字符串,對應例子,就是對漢字'獅'來說,varchar格式的字符串長度為1,nvarchar格式的字符串長度為2。
len(convert(varchar(50),N'獅lion')) --返回字符長度,'獅lion',一共5個字符,varchar格式字符
len(N'獅lion') --返回字符長度,'獅lion',一共5個字符,nvarchar格式字符
datalength(convert(varchar(50),N'獅lion')) --返回字節長度,varchar格式字符'獅lion','獅'占2個字節,
--'lion'中每個字母占用一個字節,共占用4個字節
datalength(N'獅lion') --返回字節長度,Unicode格式字符,漢字'獅'占2個字節,
--'lion'中每個字母占用2個字節,共占用8個字節
文章引用:https://blog.csdn.net/oncealong/article/details/37573927
b. 如何查看數據庫的編碼格式。
--查看sqlserver數據庫的編碼格式
SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI_KS_WS', 'CodePage');
查詢結果:
936 簡體中文GBK
950 繁體中文BIG5
437 美國/加拿大英語
932 日文
949 韓文
866 俄文
65001 unicode UFT-8
c. varchar和char和nvarchar三者的區別
- char是定長(固定長度),效率高於varchar;也就是當你輸入的字符小於你指定的數目時,例如:char(8),你輸入的字符小於8時,它會再后面補空值。當你輸入的字符大於指定的數時,它會截取超出的字符。
- varchar[n]是變長且非unicode字符數據類型,n的取值在1到8000之間,該類型英文字符占一個字節,中文字符占兩個字節。優點:更加合理利用空間,不會造成過多的浪費。
- nvarchar[n]是變長且unicode字符數據類型,n的取值在1到4000之間,該類型字符無論中英文都占取兩個字節
其中varchar和nvarchar兩字段分別有字段值:你好hello
那么varchar字段占2×2+5=9個字節的存儲空間,而nvarchar字段占7×2=14個字節的存儲空間。
如字段值只是英文可選擇varchar,而字段值存在較多的雙字節(中文、韓文等)字符時用nvarchar