达梦数据库查看表字段VARCHAR类型的长度单位是BYTE还是CHAR

本文讲述了Oracle中VARCHAR类型长度单位(LENGTH_IN_CHAR)设置的影响,介绍了如何区分字符和字节长度,并提供了一种SQL查询方法来确定字段长度单位。特别强调了数据库版本要求和不同长度单位下VARCHAR的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述

   默认情况下,LENGTH_IN_CHAR为0(默认),VARCHAR类型长度单位为字节;LENGTH_IN_CHAR为1,VARCHAR类型长度单位为字符。可以通过vparameter∗∗或者∗∗vparameter**或者**vparameter或者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;

image-20220126201203974

可以看到LENGTH_IN_CHAR默认值的情况下,指定VARCHAR类型的长度单位为字符(CHAR)时,是可以插入5个中文字符,而不指定默认长度单位为字节的情况下,是会报错“列长度超出定义”。

(2)通过上面的SQL查看表字段信息

image-20220126203306499

总结

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、方法不止一种,上述只是本人的学习测试的记录,请以实际环境测试为准。大家可以测试下上面所说的内容。

更多资讯可以上达梦技术社区了解:https://eco.dameng.com

### 如何在达梦数据库中查询表结构和字段信息 为了获取达梦数据库中的表结构及其字段详情,可以通过执行特定的 SQL 查询来实现。具体来说,可以利用 `USER_TAB_COLUMNS` 和 `USER_COL_COMMENTS` 视图联合查询得到所需的信息[^4]。 #### 使用SQL语句查询表结构 下面是一段 Python 代码示例,展示了如何构建并运行这样的查询: ```python import pymssql def get_table_structure(table_name, schema='SCHEMA_NAME'): conn = pymssql.connect(server='localhost', user='sa', password='your_password', database='test') cursor = conn.cursor() query = f""" SELECT utc.column_name AS "字段名", utc.data_type AS "字段类型", utc.data_length AS "数据长度", utc.data_precision AS "数据精度", utc.nullable AS "是否为空", ucc.comments AS "备注" FROM user_tab_columns utc, user_col_comments ucc WHERE utc.column_name = ucc.column_name AND utc.table_name = ucc.table_name AND utc.table_name = '{table_name.upper()}' AND utc.owner = '{schema}' """ try: cursor.execute(query) rows = cursor.fetchall() for row in rows: print(f"{row['字段名']} | {row['字段类型']} | {row['数据长度']} | {row['数据精度']} | {'Y' if row['是否为空'] == 'YES' else 'N'} | {row['备注']}") except Exception as e: print(e) finally: conn.close() get_table_structure('example_table') # 替换为实际存在的表名称 ``` 这段脚本连接到了本地的一个测试数据库实例,并定义了一个名为 `get_table_structure()` 的函数接收两个参数——表的名字 (`table_name`) 及其所属模式(`schema`) 。该函数内部构造了一条复杂的 SQL 命令用于提取给定表格的相关元数据,并将其打印出来以便于阅读。 请注意,在真实环境中应当替换掉上述例子中的服务器地址、用户名、密码以及其他必要的配置项以匹配目标环境的具体情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值