SQL中的数字、字母和汉字

知识点001

当变量的数据类型为VARCHAR时,变量赋值后,变量中的字符所占字节数,数字和字母是1个bytes,汉字是2个bytes;

当变量的数据类型为NVARCHAR时,变量赋值后,变量中的字符所占字节数,数字、字母和汉字,均为2个bytes。    

原因:NVARCHAR采用的字符集是unicode,unicode字符集中,无论是数字、字母、汉字,每个字符用2个bytes表示;

         VARCHAR采用的字符集为非unicode,数字和字母用1个byte表示,汉字用2个bytes表示。

学会了这点,就可以很好的去解答这个问题:SQL字符串长度计算

知识点002

假定变量的数据类型是VARCHAR(N)  ,含义是它能存储的变量空间长度是N个bytes(注意,不是bit)

Sample:

DECLARE  @name  VARCHAR(10), 

指变量@name的空间长度是10个字节。

我们知道,一个汉字占2个bytes,假如我们设计一个驾校管理系统,设计数据库的时候,将数据表字段name的数据类型设为VARCHAR(10)

10个字节,最多只能保存5个汉字,如果系统需要保存的人名长度大于5个汉字(比如俄罗斯总统普京,全名【弗拉基米尔·弗拉基米罗维奇·普京】,14个汉字,2个·字符),数据库就会截取变量值,只保存10个字节的内容,即【弗拉基米尔】,导致信息缺失。但是如果将name的数据类型声明为VARHCAR(32),问题就解决了。

PS:【弗拉基米尔·弗拉基米罗维奇·普京】汉字中间这个·(点号)

如果用搜狗输入法的符号大全中的“标点符号”栏下的点号·,则占2个字节存储空间,上文普京全名中的点号,即为这个。

如果用搜狗输入法的符号大全中的“特殊符号”栏下的点号▪,则占1个字节存储空间。

SQL验证:

DECLARE @name1  VARCHAR(10)    
DECLARE @name2  VARCHAR(32)

SET @name1 = '弗拉基米尔·弗拉基米罗维奇·普京'
SET @name2 = '弗拉基米尔·弗拉基米罗维奇·普京'

SELECT @name1 AS name1,@name2 AS name2

执行结果:

值得注意的是,下面这个数据类型的空间长度问题。

假定变量的数据类型为NVARCHAR(N),含义是它能存储的变量空间长度是(2*N)个bytes.

综上,统一概念描述为

1.SQL中,当声明一个变量的数据类型是VARCHAR(N)时,含义是:该变量可以存储空间长度为N个字节(bytes)的数据;

2.SQL中,当声明一个变量的数据类型是NVARCHAR(N)时,含义是:该变量可以容纳空间长度为2*N个字节(bytes)的数据;因该数据类型保存的数据每个字符(无论是字母、数字还是汉字)均占2个字节,所以,声明一个变量的数据类型是NVARCHAR(N)时,根据这个声明,我们可以知道,该变量可以容纳字符长度为N个字符(characters)的数据。而当你声明一个变量数据类型是VARCHAR(N)时,你就无法根据这个声明,来计算出该变量可以容纳的数据的字符长度是多少,因为该变量保存的字母、数字和汉字,所占的空间长度不都是2个字节,而是字母1个字节,数字1个字节,汉字2个字节。

即,对声明为NVARCHAR(N)类型的变量来说,你既可以知道该变量可以容纳的数据的空间长度,也可以知道该变量的字符长度;

而对声明为VARCHAR(N)类型的变量来说,你只能知道该变量可以容纳的数据的空间长度,无法知道该变量的字符长度。

SQL代码验证。PS:SQL server 版本Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64)

SQL版本查询语句:select @@VERSIONS

1 --汉字
2 CREATE TABLE dbo.Test1 (c1 NVARCHAR(4));  
3 INSERT dbo.Test1 VALUES ('美人她爹');  
4 SELECT DATALENGTH(c1) AS Bytes_of_Column_C1 FROM dbo.Test1;
5 
6 CREATE TABLE dbo.Test2 (c2 VARCHAR(8));  
7 INSERT dbo.Test2 VALUES ('美人她爹');  
8 SELECT DATALENGTH(c2) AS Bytes_of_Column_C2 FROM dbo.Test2;

执行结果:

1 --数字
2 CREATE TABLE dbo.Test3 (c3 NVARCHAR(4));  
3 INSERT dbo.Test3 VALUES ('1234');  
4 SELECT DATALENGTH(c3) AS Bytes_of_Column_C3 FROM dbo.Test3;   
5 
6 CREATE TABLE dbo.Test4 (c4 VARCHAR(8));  
7 INSERT dbo.Test4 VALUES ('12345678');  
8 SELECT DATALENGTH(c4) AS Bytes_of_Column_C4 FROM dbo.Test4; 

执行结果:

1 --字母
2 CREATE TABLE dbo.Test5 (c5 NVARCHAR(4));  
3 INSERT dbo.Test5 VALUES ('abcd');
4 SELECT DATALENGTH(c5) AS Bytes_of_Column_C5 FROM dbo.Test5;  
5 
6 CREATE TABLE dbo.Test6 (c6 VARCHAR(8));  
7 INSERT dbo.Test6 VALUES ('abcdefgh');
8 SELECT DATALENGTH(c6) AS Bytes_of_Column_C6 FROM dbo.Test6;

执行结果:

 知识点003

上文提到两个笔者自定义的概念,空间长度字符长度。借用这两个概念,说一下SQL中两个函数 LEN()和DATALENGTH()的区别。

区别1

LEN()函数返回值是字符串的字符数目(the number of characters of the specified string expression),即字符串的字符长度

DATALENGTH()函数的返回值是字符串的字符所占空间,即字符串的空间长度。

区别2

LEN()函数计算字符串的字符长度时,不计算(包含)字符串末尾空格(trailing spaces);

DATALENGTH()函数计算字符串的空间长度时,计算(包含)字符串末尾空格。

上述两点区别,SQL验证如下:

 1 DECLARE @sql_string_VARCHAR VARCHAR(100)
 2 DECLARE @sql_string_NVARCHAR NVARCHAR(100)
 3 
 4 SET @sql_string_VARCHAR = 'ab c '
 5 SET @sql_string_NVARCHAR = 'ab c '
 6 
 7 SELECT LEN(@sql_string_VARCHAR) AS characters_of_sql_string_varchar,
 8        LEN(@sql_string_NVARCHAR) AS characters_of_sql_string_nvarchar
 9 SELECT DATALENGTH(@sql_string_VARCHAR) AS Bytes_of_sql_string_varchar,
10        DATALENGTH(@sql_string_NVARCHAR) AS Bytes_of_sql_string_nvarchar

执行结果:

 

posted @ 2022-04-03 18:44  美人她爹  阅读(1163)  评论(0编辑  收藏  举报