LENGTH_IN_CHAR
VARCHAR 类型对象的长度是否以字符为单位。
1:是,设置为以字符为单位时,定义长度并非真正按照字符长度调整,而是将存储长度值按照理论字符长度进行放大。
所以会出现实际可插入字符数超过定义长度的情况,这种情况也是允许的。
同时,存储的字节长度 8188 上限仍然不变,也就是说,即使定义列长度为8188 字符,其实际能插入的字符串占用总字节长度仍然不能超过 8188;
0:否,所有 VARCHAR 类型对象的长度以字节为单位
CHARSET
字符集选项。0 代表 GB18030;1 代表UTF-8;2 代表韩文字符集 EUC-KR
CHARSET=0代表使用GB18030,即一个中文两个字节。CHARSET=1代表使用UTF-8,即一个中文3个字节。
按照定义理解,我做了以下实验:
初始化实例:
./dminit PATH=/dm/data/ INSTANCE_NAME=GRP1_LOCAL_01 PAGE_SIZE=32 EXTENT_SIZE=32 LOG_SIZE=2048 CHARSET=0 LENGTH_IN_CHAR=N AUTO_OVERWRITE=2
SQL> CREATE TABLE TEST (ID INT,NAME VARCHAR(8));
操作已执行
已用时间: 20.546(毫秒). 执行号:59400.
SQL> INSERT INTO TEST VALUES (1,'娄心如');
影响行数 1
已用时间: 0.697(毫秒). 执行号:59401.
SQL> COMMIT;
操作已执行
已用时间: 2.728(毫秒). 执行号:59402.
SQL> INSERT INTO TEST VALUES (2,'娄心如娄');
影响行数 1
已用时间: 1.222(毫秒). 执行号:59403.
SQL> COMMIT;
操作已执行
已用时间: 1.866(毫秒). 执行号:59404.
SQL> INSERT INTO TEST VALUES (3,'娄心如娄心');
INSERT INTO TEST VALUES (3,'娄心如娄心');
[-6169]:列[NAME]长度超出定义.
已用时间: 1.314(毫秒). 执行号:0.
SQL> INSERT INTO TEST VALUES (3,'娄心如娄L');
INSERT INTO TEST VALUES (3,'娄心如娄L');
[-6169]:列[NAME]长度超出定义.
已用时间: 0.370(毫秒). 执行号:0.
SQL> SELECT DATA_LENGTH,NAME,LENGTH(NAME),LENGTHB(NAME) FROM TEST,DBA_TAB_COLUMNS
WHERE TABLE_NAME='TEST' AND COLUMN_NAME='NAME';2
行号 DATA_LENGTH NAME LENGTH(NAME) LENGTHB(NAME)
---------- ----------- -------- ------------ -------------
1 8 娄心如 3 6
2 8 娄心如娄 4 8
已用时间: 5.706(毫秒). 执行号:59407.
可以看出在字段长度为9时就报错超出长度,只存储了4个中文字符。
初始化实例:
./dminit PATH=/dm/data/ INSTANCE_NAME=GRP1_LOCAL_01 PAGE_SIZE=32 EXTENT_SIZE=32 LOG_SIZE=2048 CHARSET=0 LENGTH_IN_CHAR=Y AUTO_OVERWRITE=2
SQL> CREATE TABLE TEST (ID INT,NAME VARCHAR(8));
操作已执行
已用时间: 14.944(毫秒). 执行号:59400.
SQL> INSERT INTO TEST VALUES (1,'娄心如');
COMMIT;
影响行数 1
已用时间: 0.698(毫秒). 执行号:59401.
SQL> 操作已执行
已用时间: 4.695(毫秒). 执行号:59402.
SQL> INSERT INTO TEST VALUES (2,'娄心如娄');
COMMIT;
影响行数 1
已用时间: 0.473(毫秒). 执行号:59403.
SQL> 操作已执行
已用时间: 3.560(毫秒). 执行号:59404.
SQL> INSERT INTO TEST VALUES (3,'娄心如娄心');
COMMIT;
影响行数 1
已用时间: 0.483(毫秒). 执行号:59405.
SQL> 操作已执行
已用时间: 1.993(毫秒). 执行号:59406.
SQL> INSERT INTO TEST VALUES (3,'娄心如娄心如');
COMMIT;
影响行数 1
已用时间: 0.478(毫秒). 执行号:59407.
SQL> 操作已执行
已用时间: 3.593(毫秒). 执行号:59408.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄');
COMMIT;
影响行数 1
已用时间: 0.484(毫秒). 执行号:59409.
SQL> 操作已执行
已用时间: 5.337(毫秒). 执行号:59410.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心');
COMMIT;
影响行数 1
已用时间: 0.516(毫秒). 执行号:59411.
SQL> 操作已执行
已用时间: 3.734(毫秒). 执行号:59412.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心如');
COMMIT;
INSERT INTO TEST VALUES (5,'娄心如娄心如娄心如');
[-6169]:列[NAME]长度超出定义.
已用时间: 0.485(毫秒). 执行号:0.
SQL> 操作已执行
已用时间: 0.247(毫秒). 执行号:59414.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心R');
COMMIT;
INSERT INTO TEST VALUES (5,'娄心如娄心如娄心R');
[-6169]:列[NAME]长度超出定义.
已用时间: 0.452(毫秒). 执行号:0.
SQL> 操作已执行
已用时间: 0.212(毫秒). 执行号:59416.
SQL> SELECT DATA_LENGTH,NAME,LENGTH(NAME),LENGTHB(NAME) FROM TEST,DBA_TAB_COLUMNS
WHERE TABLE_NAME='TEST' AND COLUMN_NAME='NAME';
2
行号 DATA_LENGTH NAME LENGTH(NAME) LENGTHB(NAME)
---------- ----------- ---------------- ------------ -------------
1 8 娄心如 3 6
2 8 娄心如娄 4 8
3 8 娄心如娄心 5 10
4 8 娄心如娄心如 6 12
5 8 娄心如娄心如娄 7 14
6 8 娄心如娄心如娄心 8 16
6 rows got
可以看出在字段NAME可以存储8个中文字符,实际最大存储长度为16,是长度定义的2倍。
初始化实例:
./dminit PATH=/dm/data/ INSTANCE_NAME=GRP1_LOCAL_01 PAGE_SIZE=32 EXTENT_SIZE=32 LOG_SIZE=2048 CHARSET=1 LENGTH_IN_CHAR=N AUTO_OVERWRITE=2
SQL> CREATE TABLE TEST (ID INT,NAME VARCHAR(8));
操作已执行
已用时间: 16.185(毫秒). 执行号:59400.
SQL> INSERT INTO TEST VALUES (1,'娄心RU');
影响行数 1
已用时间: 0.751(毫秒). 执行号:59401.
SQL> COMMIT;
操作已执行
已用时间: 3.682(毫秒). 执行号:59402.
SQL> INSERT INTO TEST VALUES (2,'娄心如');
INSERT INTO TEST VALUES (2,'娄心如');
[-6169]:列[NAME]长度超出定义.
已用时间: 0.429(毫秒). 执行号:0.
SQL> SELECT DATA_LENGTH,NAME,LENGTH(NAME),LENGTHB(NAME) FROM TEST,DBA_TAB_COLUMNS
WHERE TABLE_NAME='TEST' AND COLUMN_NAME='NAME';
2
行号 DATA_LENGTH NAME LENGTH(NAME) LENGTHB(NAME)
---------- ----------- -------- ------------ -------------
1 8 娄心RU 4 8
可以看出在CHARSET=1的情况下,一个中文占用3个字符,NAME只能存储两个中文两个英文字符,总长度8.
初始化实例:
./dminit PATH=/dm/data/ INSTANCE_NAME=GRP1_LOCAL_01 PAGE_SIZE=32 EXTENT_SIZE=32 LOG_SIZE=2048 CHARSET=1 LENGTH_IN_CHAR=Y AUTO_OVERWRITE=2
SQL> CREATE TABLE TEST (ID INT,NAME VARCHAR(8));
操作已执行
已用时间: 14.705(毫秒). 执行号:59400.
SQL> INSERT INTO TEST VALUES (1,'娄心RU');
COMMIT;
影响行数 1
已用时间: 0.656(毫秒). 执行号:59401.
SQL> 操作已执行
已用时间: 4.171(毫秒). 执行号:59402.
SQL> INSERT INTO TEST VALUES (2,'娄心如');
COMMIT;
影响行数 1
已用时间: 0.435(毫秒). 执行号:59403.
SQL> 操作已执行
已用时间: 1.745(毫秒). 执行号:59404.
SQL> INSERT INTO TEST VALUES (3,'娄心如娄心');
COMMIT;
影响行数 1
已用时间: 0.517(毫秒). 执行号:59405.
SQL> 操作已执行
已用时间: 3.732(毫秒). 执行号:59406.
SQL> INSERT INTO TEST VALUES (3,'娄心如娄心如');
COMMIT;
影响行数 1
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄');
COMMIT;
影响行数 1
已用时间: 0.437(毫秒). 执行号:59409.
SQL> 操作已执行
已用时间: 3.470(毫秒). 执行号:59410.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心');
COMMIT;
影响行数 1
已用时间: 0.446(毫秒). 执行号:59411.
SQL> 操作已执行
已用时间: 4.574(毫秒). 执行号:59412.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心如');
COMMIT;
影响行数 1
已用时间: 0.438(毫秒). 执行号:59413.
SQL> 操作已执行
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心如娄');
COMMIT;
影响行数 1
已用时间: 0.534(毫秒). 执行号:59417.
SQL> 操作已执行
已用时间: 1.923(毫秒). 执行号:59418.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心如娄L');
影响行数 1
已用时间: 0.412(毫秒). 执行号:59419.
SQL> COMMIT;
操作已执行
已用时间: 2.023(毫秒). 执行号:59420.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心如娄LO');
影响行数 1
已用时间: 0.417(毫秒). 执行号:59421.
SQL> INSERT INTO TEST VALUES (5,'娄心如娄心如娄心如娄LOU');
INSERT INTO TEST VALUES (5,'娄心如娄心如娄心如娄LOU');
[-6169]:列[NAME]长度超出定义.
已用时间: 0.476(毫秒). 执行号:0.
SQL> SELECT DATA_LENGTH,NAME,LENGTH(NAME),LENGTHB(NAME) FROM TEST,DBA_TAB_COLUMNS
WHERE TABLE_NAME='TEST' AND COLUMN_NAME='NAME';
2
行号 DATA_LENGTH NAME LENGTH(NAME) LENGTHB(NAME)
---------- ----------- -------------------------------- ------------ -------------
1 8 娄心RU 4 8
2 8 娄心如 3 9
3 8 娄心如娄心 5 15
4 8 娄心如娄心如 6 18
5 8 娄心如娄心如娄 7 21
6 8 娄心如娄心如娄心 8 24
7 8 娄心如娄心如娄心如 9 27
8 8 娄心如娄心如娄心如娄 10 30
9 8 娄心如娄心如娄心如娄L 11 31
10 8 娄心如娄心如娄心如娄LO 12 32
可以看出,在CHARSET=1,可以存储3个中文字符的情况下,LENGTH_IN_CHAR=1,最终NAME字段实际存储长度为32,为定义长度的4倍。
在使用GB18030作为字符集类型,且LENGTH_IN_CHAR为0时,只存储了4个中文字符,没有进行自动扩充。LENGTH_IN_CHAR为1时,实际最大存储长度为16,是长度定义的2倍;
在使用UTF-8作为字符集类型,且LENGTH_IN_CHAR为0时,只存储了两个中文字符加两个英文字符。LENGTH_IN_CHAR=1,实际最大存储长度为32,为定义长度的4倍。
文章
阅读量
获赞