描述
默认情况下,LENGTH_IN_CHAR为0(默认),VARCHAR类型长度单位为字节;LENGTH_IN_CHAR为1,VARCHAR类型长度单位为字符。可以通过voption查看LENGTH_IN_CHAR初始化参数设置的值。
注意:LENGTH_IN_CHAR为实例初始化参数,只能在创建实例时指定,实例创建之后无法中途修改。
除了通过在创建实例时设置LENGTH_IN_CHAR=1以外,在LENGTH_IN_CHAR=0时,可以指定表的字段VARCHAR类型长度单位为字符,比如:
CREATE TABLE T1
(
C1 VARCHAR2(5), ---长度单位默认为byte
C2 VARCHAR2(5 CHAR), ---指定长度单位为CHAR
C3 VARCHAR(5),
C4 VARCHAR(5 CHAR),
C5 NVARCHAR(5),
C6 NVARCHAR(5 CHAR)
);
那么,针对上面这种建表语句中指定VARCHAR类型长度单位的情况,在VARCHAR类型长度单位为字节(LENGTH_IN_CHAR为0) 的数据库实例中如何查看表中VARCHAR类型字段的长度单位呢?
在SYSCOLUMNS、DBA_TAB_COLUMNS、DBA_TAB_COLS这些系统表和视图中无法直接很明确的查到对应列的类型长度单位是否是CHAR(其中DBA_TAB_COLUMNS、DBA_TAB_COLS都是基于SYSCOLUMNS系统表的视图),需要使用SQL语句根据SCALE字段值进行判断。这里直接通过SYSCOLUMNS进行查看,根据SCALE字段值为7进行判断(注意:不是所有的版本都可以,版本要求从DM V8 1-1-190左右的版本及以后的版本),SQL语句如下:
WITH TABS AS
(select O1.NAME SCHEMA_NAME,
O2.NAME TABLE_NAME,
COL.NAME COLUMN_NAME,
COL.TYPE$ DATA_TYPE,
CASE
WHEN SF_GET_LENGTH_IN_CHAR() = 0
AND COL.TYPE$ IN ('VARCHAR', 'VARCHAR2', 'NVARCHAR', 'NVARCHAR2')
AND COL.SCALE = 7
THEN COL.LENGTH$ || ' CHAR' /*LENGTH_IN_CHAR=0,VARCHAR类型SCALE值为7,则长度为CHAR*/
WHEN COL.TYPE$ IN ('TIMESTAMP','DATETIME')
THEN COL.SCALE /*TIMESTAMP、DATETIME类型 DATA_LENGTH为SCALE*/
ELSE
COL.LENGTH$
END DATA_LENGTH,
COL.DEFVAL DATA_DEFAULT,
CASE WHEN COL.NULLABLE$='N' THEN 'NOT NULL' ELSE COL.NULLABLE$ END NULLABLE
from SYSCOLUMNS COL, SYSOBJECTS O1, SYSOBJECTS O2
WHERE COL.ID = O2.ID
AND O1.TYPE$ = 'SCH'
AND O2.TYPE$ = 'SCHOBJ'
AND O2.SUBTYPE$ = 'UTAB'
AND O1.ID = O2.SCHID)
SELECT * FROM TABS WHERE DATA_LENGTH LIKE '%CHAR%';
/*SELECT DISTINCT SCHEMA_NAME,TABLE_NAME FROM TABS WHERE SCHEMA_NAME = 'SYSDBA' AND DATA_LENGTH LIKE '%CHAR%';*/
测试
(1)创建测试表
create table T1
(
C1 VARCHAR2(5),
C2 VARCHAR2(5 CHAR),
C3 VARCHAR(5),
C4 VARCHAR(5 CHAR),
C5 NVARCHAR(5),
C6 NVARCHAR(5 CHAR)
);
INSERT INTO T1(C1) VALUES('中文中文中');
INSERT INTO T1(C2) VALUES('中文中文中');
INSERT INTO T1(C3) VALUES('中文中文中');
INSERT INTO T1(C4) VALUES('中文中文中');
INSERT INTO T1(C5) VALUES('中文中文中');
INSERT INTO T1(C6) VALUES('中文中文中');
COMMIT;
可以看到LENGTH_IN_CHAR默认值的情况下,指定VARCHAR类型的长度单位为字符(CHAR)时,是可以插入5个中文字符,而不指定默认长度单位为字节的情况下,是会报错“列长度超出定义”。
(2)通过上面的SQL查看表字段信息
总结
1、查询SQL对数据库版本有要求,需要数据库版本是DM V8 1-1-190左右及以上的版本(本次测试的最高的版本为2021年12月版本)。
2、在初始化参数“VARCHAR类型长度是否以字符为单位”(即LENGTH_IN_CHAR)设置为1(以字符为单位)时,表的字段类型无论是VARCHAR(10 CHAR)还是VARCHAR(10)都是以字符为单位。在LENGTH_IN_CHAR=0时,VARCHAR(10 CHAR)可以存10个字符长度数据(比如10个中文汉字),VARCHAR(10)可以存10个字节长度数据。所以上面的查询SQL中只对LENGTH_IN_CHAR=0的情况下显示长度为多少CHAR。(大家可以在自己的环境测试下)
3、在DM V8的2021年12月左右的版本中NVARCHAR类型的长度都是以字符为单位,无论是LENGTH_IN_CHAR=0还是LENGTH_IN_CHAR=1,NVARCHAR的长度单位都是字符。之前的版本还是受LENGTH_IN_CHAR参数控制。
4、方法不止一种,上述只是本人的学习测试的记录,请以实际环境测试为准。大家可以测试下上面所说的内容。