宁武皇仁光九年锦文轩刻本《异闻录》载: 扶桑画师浅溪,居泰安,喜绘鲤。院前一方荷塘,锦鲤游曳,溪常与嬉戏。 其时正武德之乱,潘镇割据,战事频仍,魑魅魍魉,肆逆于道。兵戈逼泰安,街邻皆逃亡,独溪不舍锦鲤,未去。 是夜,院室倏火。有人入火护溪,言其本鲤中妖,欲取溪命,却生情愫,遂不忍为之。翌日天明,火势渐歇,人已不见。 溪始觉如梦,奔塘边,但见池水干涸,莲叶皆枯,塘中鲤亦不知所踪。 自始至终,未辨眉目,只记襟上层迭莲华,其色魅惑,似血着泪。 后有青岩居士闻之,叹曰:魑祟动情,必作灰飞。犹蛾之投火耳,非愚,乃命数也。 ————《锦鲤抄》

VARCHAR与VARCHAR2在Oracle和达梦的表现差异

达梦数据库与Oracle数据库在VARCHAR上的异同

在Oracle中

不同点:

varchar:varchar存放可变长度的字符串,最大长度是2000,对于空串,varchar仍按空串处理。

varchar2:也是存放可变长度的字符串,最大长度是4000。VARCHAR2把空串等同于null处理。

相同点:

根据编码不同,可容纳汉字不同:

具体要看字符集情况。比如GBK,汉字就会占两个字节,英文1个;如果是UTF-8,汉字一般占3个字节,英文还是1个

-- 比如表设计时 s_name 类型为varchar2(10),那最大容纳汉字只能是3个,多了会报错,比如输入“测试最大长度”时:
-- ORA-12899: 列 "FIPT_DEV"."TEST"."S_NAME" 的值太大 (实际值: 18, 最大值: 10)
-- 输入非汉字字符时也同理:数字和英文字符都是占一个长度,即默认varchar2(10)是varchar(10 byte),10个字节长度
-- 输入“测试abcdefg3” 时:
-- 报错:ORA-12899: 列 "FIPT_DEV"."TEST"."S_NAME" 的值太大 (实际值: 14, 最大值: 10)

-- 设计时字符与字节认知区别:
-- 占用字符数
select length('测试占用字符2') from dual;
-- 返回7
-- 占用字节数 (即varchar2 对应)
select lengthb('测试占用字节数2') from dual;
-- 返回22
-- ps:这里是utf8 ,所以一个汉字占3 字节

在达梦8中

达梦8的语法基本是按照Oracle来的

所以,这里不比较varchar和varchar2,只以varchar为例区分字符集和初始化参数LENGTH_IN_CHAR不同对应的四种情况。

LENGTH_IN_CHAR=0表示不启用,为1则表示启用以字符为单位,将存储长度值按照理论字符长度进行放大,但最大存储长度不能超过8188个字节,放大规则(UTF8可乘以4,GBK可乘以2)

如下:

-- 1.查看字符集
select unicode from dual;
-- 这里我的字符集为 UTF-8

-- 2.查看初始化参数 LENGTH_IN_CHAR
select * from SYS.V$PARAMPTER where name like '%LENGTH_IN_CHAR%';
-- 这里我的是 LENGTH_IN_CHAR的value=1

-- UTF8且LENGTH_IN_CHAR=1则varchar(5)的列可以容纳20(5*4=20)个数字或字符的字符串,
-- 如果是中文,因为UTF-8字符集下中文与字母占用比例为3:1,也就是(5*4)/3 = 6个汉字
-- UTF8且LENGTH_IN_CHAR=0则varchar(5)的列可以容纳5个数字或字符的字符串,
-- 如果是中文,因为UTF-8字符集下中文与字母占用比例为3:1,也就是5/3 = 1个汉字

-- GBK且LENGTH_IN_CHAR=1则varchar(5)的列可以容纳5*2=10个数字或字符的字符串,
-- 如果是中文,因为GBK字符集下中文与字母占用比例为2:1,也就是(5*2)/2 = 5个汉字
-- GBK且LENGTH_IN_CHAR=0则varchar(5)的列可以容纳5个数字或字符的字符串,
-- 如果是中文,因为GBK字符集下中文与字母占用比例为2:1,也就是5/2 = 2个汉字

posted @ 2024-04-16 09:58  哒布溜  阅读(2109)  评论(0编辑  收藏  举报