点击蓝色字关注“SQL数据库运维”,回复“SQL”获取2TB学习资源!
如果是字符串型字段,是设为varchar2还是nvarchar2好,如果设置了最大长度是多少?网上众说纷纭,下文试图从实验入手,亲身获取第一手资料,免得被人误导。
首先,要判断varchar2和nvarchar2存入字符的字节长度,必须先看看系统设置的字符集,如果字符集设置的不一样,结果就会显示出的不一样,文末有解释:
SELECT * FROM Nls_Database_Parameters w where w.PARAMETER like '%CHARACTERSET%'

让我们先建一个实验表test_01:
create table test_01(id int,name nvarchar2(10),remark varchar2(10),primary key(id));
准备执行的SQL插入语句,大家可先预判下执行结果。
insert into test_01(id,name,remark) values(1,'离离原上草一岁一枯荣','离离原上草');insert into test_01(id,name,remark) values(2,'离离原上草一岁一枯荣','离离原上草一');insert into test_01(id,name,remark) values(3,'1234567890','离离原上草');insert into test_01(id,name,remark) values(4,'12345678901','离离原上草');insert into test_01(id,name,remark) values(5,'1234567890','1234567890');insert into test_01(id,name,remark) values(6,'1234567890','12345678901');

第二句:insert into test_01(id,name,remark) values(2,'离离原上草一岁一枯荣','离离原上草一');
这一句remark里塞入了'离离原上草一',这是六个汉字,相当于12个英数字,所以超限了,故插入失败。
执行结果,提示如下:

第三句:insert into test_01(id,name,remark) values(3,'1234567890','离离原上草');
这一句name里塞'1234567890',这是正好十个英数字,没有超限;remark里塞'离离原上草',这是五个汉字相当于十个英数字,也没有超限,故成功插入.
执行结果:

第四句:insert into test_01(id,name,remark) values(4,'12345678901','离离原上草');
这一句往name里塞'12345678901',这段文本是十一个英数字,超过限度,故插入失败。
执行结果:

第五句:insert into test_01(id,name,remark) values(5,'1234567890','1234567890');
这一句往name和remark里塞的都是'1234567890',这段文本是十位英数字,故不超限,能成功插入。
执行结果:

第六句:insert into test_01(id,name,remark) values(6,'1234567890','12345678901');
这一句name不超,但remark里塞'12345678901',这是十一个英数字,已经超过,故插入失败。
执行结果:

SELECT * FROM test_01;

结论:
nvarchar2(MAX)不分字符集,规定多少个就是多少个,英语字母数字汉字平假名片假名都一视同仁,没有换算时乘二除二的麻烦;
varchar2(MAX) 区分字符集,能容纳MAX个英数字,只能容纳MAX/2个汉字,换算有点烦。
为省心计,最好文本字段都按nvarchar2类型来设定。
扩展:
大家都知道Oracle里有个仿佛是硬编码的字符串上限,即最多容纳4000个英数字,即varchar2(n)型字段,n的上限便是4000;nvarchar2(N),N的上限便是4000/2=2000。
咱们可以验证一下nvarchar2型字段:
--新建一个测试表,设置nvarchar2(2001)create table tb(id int,remark nvarchar2(2001),primary key(id));
执行结果提示:创建失败

--新建一个测试表,设置nvarchar2(2000)create table tb(id int,remark nvarchar2(2000),primary key(id));

--新建一个测试表,设置varchar2(4001)create table tb2(id int,name varchar2(4001),remark nvarchar2(2000),primary key(id));

--新建一个测试表,设置varchar2(4000)create table tb2(id int,name varchar2(4000),remark nvarchar2(2000),primary key(id));

如果oracle配置如下:
NLS_CHARACTERSET AL32UTF8
NLS_NCHAR_CHARACTERSET AL16UTF16
说明,varchar2是按UTF8来存中文,一个常用中文字符占3个字节,所以varchar2(10)只能存下3个汉字,占用9个字节(因为这里面的10,是指字节的长度10,还有一种声明方式可以让varchar2(10 char),可以让他存10个字符,占30个字节)
而nvarchar2默认为UTF16,一个常用中文字符占2个字节,所以nvarchar2(10)能存下10个汉字,占用20个字节(因为这里面的10,是指字符的长度10),
其实oracle规定了无论varchar2和nvarchar2,最大长度用字节来算,都是4000,所以oracle官网有句话:
The maximum column size allowed is 4000 characters when the national character set is UTF8 and 2000 when it is AL16UTF16.
意思是,如果NLS_NCHAR_CHARACTERSET设置为UTF8,那么你就能创建nvarchar2(4000)的字段。
文章参考资料:博客园-逆火狂飙—https://www.cnblogs.com/heyang78/p/15269468.html
oracle官网关于nvarchar类型的解释:https://docs.oracle.com/cd/B19306_01/server.102/b14225/ch7progrunicode.htm#s

点击关注“SQL数据库运维”,后台或浏览至公众号文章底部点击“发消息”回复关键字:进群,带你进入高手如云的技术交流群。后台回复关键字:SQL,获取学习资料。
动动小手点击加关注呦☟☟☟




