###############

sample 1: NLS_LENGTH_SEMANTICS

1、数据库字符集选择的是NLS_CHARACTERSET=UTF8,如果NLS_CHARACTERSET=ZHS16GBK就不会有这种情况;

2、原库中NLS_LENGTH_SEMANTICS=CHAR,新库中NLS_LENGTH_SEMANTICS=BYTE;

3、主要是第2条造成的,如果字符集是UTF8,字段类型VARCHAR2中一个字符占几个字节是由NLS_LENGTH_SEMANTICS参数决定的,
    如果是BYTE,则一个字符占一个字节,如果是CHAR,则一个字符占四个字节。
    通过下面的语句可以查看实际的data_length长度
    select table_name, column_name, data_type, data_length from cols

https://www.2cto.com/database/201502/376311.html

上面邮件,出于对隐私的保护,对发件人,收件人,数据库名称进行了隐涂。

邮件内容主要意思是:

(1) 源端和目标端数据库的字符集均为SIMPLIFIED CHINESE_CHINA.UTF8,但是源端数据库NLS_LENGTH_SEMANTICS参数的值为char,目标数据库NLS_LENGTH_SEMANTICS参数的值为byte

(2) 邮件中对知识错误的理解:由于源端数据库NLS_LENGTH_SEMANTICS参数的值为char(把1个汉字当成一个字节),目标数据库NLS_LENGTH_SEMANTICS参数的值为byte(把1个汉字占3个字节),所以,源端Varchar2(16)能存储16个汉字,而目标端Varchar2(16)即只能存5个汉字,导致源数据的数据无法插入到目标端数据库中去

(3) 邮件中错误的建议解决办法:将目标端数据库的NLS_LENGTH_SEMANTICS参数的值,改成与源端数据库NLS_LENGTH_SEMANTICS参数相同的值

2、知识的梳理

2.1 NLS_LENGTH_SEMANTICS参数的用途

NLS_LENGTH_SEMANTICS参数是一个专为创建CHAR和VARCHAR2两种字符型的列时,指定使用的字节长度,还是使用字符长度的定义方式,有byte和char两种值,默认为byte。

当设置该参数为BYTE时,定义CHAR列或VARCHAR2列采用字节长度方式;当设置该参数为CHAR时,定义CHAR列或VARCHAR2列采用字符长度的方式。该参数对于数据库中已经存在的列不具备任何用途,只是在创建表,或修改表的列时才具有意义。

2.2 字节长度与字符长度的区别

此章节从百度文库摘抄,原文地址为:https://baike.baidu.com/link?url=gtnaOI4rLZejxtdNISG3z8Vm1IpobqAB4nv3TRSnKh9RwTo2eR8eRkUWUUv00J7INVvGPQ2O51o-r77SfyIwT_

(1)ASCII码:

一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数,换算为十进制。最小值0,最大值255。如一个ASCII码就是一个字节。

(2)UTF-8编码:

一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。

(3) Unicode编码:

一个英文等于两个字节,一个中文(含繁体)等于两个字节。

(4) 符号:

一个英文标点占一个字节,一个中文标点占两个字节。举例:英文句号“.”占1个字节的大小,中文句号“。”占2个字节的大小。

3、邮件中对知识错误的理解

邮件中要求修改目标端数据库NLS_LENGTH_SEMANTICS参数,是完全错误的解决方案,之所以出现这样的情况,是因为此开发人员对NLS_LENGTH_SEMANTICS参数的理解不正确。

该开发人员,错误的将NLS_LENGTH_SEMANTICS参数理解成,只要该参数一改,数据库中所有的涉及CHAR和VARCHAR2两种字符型的列的长度类型都发生变化了。

其实不是,NLS_LENGTH_SEMANTICS参数的值,不对已经存在的列产生任何影响,只是在创建表中的列时,默认的指定列长度类型为byte还是char,如果在创建或修改表的列时指定了长度类型,完全覆盖NLS_LENGTH_SEMANTICS参数的值。

4、剖析问题的真正原因

其实,该开发人员所面对的真正问题原因,是源端表字段的长度类型与目标端表字段长度的类型不一致所致。

问题根本原因搞清楚了,解决方案就容易了,将目标端表的字段长度类型修改成与源端一样,不就解决了木。何必修改数据库参数还重启数据库的。

下面以三条create table的语句说清楚NLS_LENGTH_SEMANTICS参数的用途

(1)两条指定长度类型的SQL语句

create table tab_t(t_name varchar2(20byte));

create table tab_t(t_name varchar2(20char));

上面两条语句,唯一的不同,就是在指定列长度为20后,再指定长度的类型,类型的值不同。

(2)不指定长度类型的SQL语句

create table tab_t(t_name varchar2(20));

这条语句,在指定列的长度为20后,并未指定长度的类型,那它的类型会是什么呢,这个就是由NLS_LENGTH_SEMANTICS参数的值所决定了,该参数值可以在会话级设定。

5、测试验证

5.1 确认数据库的字符集类型

SQL> select *from nls_database_parameters t where t.parameter='NLS_CHARACTERSET';

PARAMETER VALUE

------------------------------ --------------------------------------

NLS_CHARACTERSET AL32UTF8

5.2 创建列长度类型为byte的表并测试可插入数据长度

(1)查看NLS_LENGTH_SEMANTICS参数当前值

SQL> selectname,value from v$parameter where upper(name)='NLS_LENGTH_SEMANTICS';

NAME VALUE

------------------------------ -------------------------------

nls_length_semantics BYTE

(2)创建带列长度类型为byte的表

SQL>create table tab_t(t_name varchar2(3));

(3)查看新创建的tab_t表的t_name列长度类型

SQL>select table_name,column_name,data_type,char_usedfrom dba_tab_columns where table_name='TAB_T'

TABLE_NAME COLUMN_NAME DATA_TYPE CHAR_USED

-------------------- ----------------------- ------------------------- -----------------------------

TAB_T T_NAME VARCHAR2 B

(4)插入英文字符串数据测试

$ export NLS_LANG=AMERICAN_AMERICA.UTF8

--注意上面这一条,设置客户端字符集很重要,如果环境变量有设置,此步可以跳过。如果发生复杂的字符集转换,一个中文汉字有可能会占用6个字节

SQL> insert into tab_t values ('ZHO');

1 row created.

SQL> insert into tab_t values ('ZHON');

insert into tab_t values ('ZHON')

*

ERROR at line 1:

ORA-12899: value too large for column "SYS"."TAB_T"."T_NAME" (actual: 4,maximum: 3)

从上面测试数据来看,插入三个英文字母成功,在插入四个字母的字符串时失败,提示实际长度为4,但maximum只有3

(5) 插入中文字符串数据测试

1)先计划一下“中”字占用几个字节

SQL> SELECT LENGTHB('中') FROM DUAL;

LENGTHB('中')

-------------

3

2)插入一个中文汉字

SQL> insert into tab_t values ('中');

1 row created.

3)插入两个中文汉字

SQL> insert into tab_t values ('中国');

insert into tab_t values ('中国')

*

ERROR at line 1:

ORA-12899: value too large for column "SYS"."TAB_T"."T_NAME" (actual: 6, maximum: 3)

插入两个中文汉字失败,实际长度为6,字段maximum只有3,在此验证确定,在UTF8下,一个中文汉字占3个字符。

5.3 将tab_t表的t_name列更改成char长度类型并做可插入长度测试

(1)将tab_t表的t_name列长度类型更改成char

SQL>alter table tab_t modify (t_name varchar2(3char));

(2)验证修改结果

SQL> selecttable_name,column_name,data_type,char_used from dba_tab_columns wheretable_name='TAB_T' ;

TABLE_NAME COLUMN_NAME DATA_TYPE CHAR_USED

-------------------- ----------------------- ------------------------- -----------------------------

TAB_T T_NAME VARCHAR2 C

(3) 插入两个中文汉字

SQL> insert into tab_t values ('中国');

1 row created.

varchar2(3 char)插入两个中文汉字成功

6、小结

经过对开发人员的需求进行判断,以及纠正其对NLS_LENGTH_SEMANTICS参数用途错误的理解,用修改表字段长度类型的方式解决其面临的实际问题,避免了一次不必要的数据库重启,以及问题得到真正的解决。

#########2

oracle导出、导入表和字段的注释

--导出表的注释

   set heading off; 
   set echo off; 
   set feedback off; 
   set termout on; 
   spool C:\table_comment.sql; 
   SELECT 'comment on table ' || t.table_name || ' is '''  || t.comments ||''';' FROM user_tab_comments t; 
   spool off; 
  
   --导入表的注释
     @ C:\table_comment.sql;
 
   --导出表字段的注释
   set heading off; 
   set echo off; 
   set feedback off; 
   set termout on; 
   spool C:\column_comment.sql; 
   SELECT 'comment on column ' || t.table_name || '.' || t.column_name || ' is '''  || t.comments ||''';' FROM user_col_comments t; 
   spool off; 
 
  --导入表字段的注释
     @ C:\column_comment.sql;
 
https://blog.csdn.net/shipeng1022/article/details/53066558

oracle 数据导入 数据和备注(comment)乱码问题解决办法

 

数据库的 2个参数 NLS_LENGTH_SEMANTICS 说明,comment 说明的更多相关文章

  1. jmeter 获取数据库表数据作为参数

    jmeter - 获取数据库表数据作为参数 在jmeter中使用数据库表数据首先需要设置数据库连接,然后在创建JDBC取样器 1.创建配置元件 JDBC Connection Configuratio ...

  2. Django---ORM的常用字段和自定义字段,DjangoORM字段与数据库类型对应,字段参数和Meta的参数,Django的admin操作,13中orm操作方法,单标的双下方法

    Django---ORM的常用字段和自定义字段,DjangoORM字段与数据库类型对应,字段参数和Meta的参数,Django的admin操作,13中orm操作方法,单标的双下方法 一丶ORM常用字段 ...

  3. Django创建数据库常用字段及参数

    Django创建数据库常用字段及参数 常用字段 1.models.AutoField 自增列= int(11) 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列 ...

  4. MySQL数据库my.cnf性能参数如何调优

    提供一个MySQL 5.6版本适合在1GB内存VPS上的my.cnf配置文件.配置文件可以到这里下载:: 下载my.cnf [client] port = 3306 socket = /tmp/mys ...

  5. Mysql数据库操作系统及配置参数优化

    数据库结构优化 表的水平拆分常用的水平拆分方法为:1.对 customer_id进行 hash运算,如果要拆分成5个表 则使用mod(customer_id,5)取出0-4个值2.针对不同的 hash ...

  6. 关于vs调用数据库存储过程 返回输出参数的一些总结

    1.直接上练习的存储过程,方便回想 create proc proc_output @totlecount int output, @pageIndex int, @pageSize intas de ...

  7. 编程开发之--Oracle数据库--存储过程在out参数中使用光标(3)

    在本系列学习随笔中的第2节我们留下了2个问题,我们现在讨论在out参数中使用光标. 1.要在out参数中使用光标,我们需要申明一个包的结构,包的结构分为包头和包体,包头只负责申明,包体只负责实现.包头 ...

  8. log4j输出到数据库(输出自定义参数、分级保存)

    转载自:http://wallimn.iteye.com/blog/1525819 Log4J日志输出到数据库中,且保存些用户自定义的参数,如用户ID,且配置仅输出指定级别的日志.  配置文件如下:  ...

  9. Jmeter进阶技能-数据库信息,传递参数

    因为项目的原因,假设我们要实现如下要求:从数据库的用户表里获取用户信息,并作为参数全部传递给登录请求,分别完成登录操作. 01Jmeter连接数据库 1.添加JDBC Connection Confi ...

随机推荐

  1. DNSmasq

    是一款轻便的主要用于个人电脑的DNS:占用的端口是53(和DNS服务的bind的端口一致):我之所以关注它,就是因为在安装DCOS的时候是不允许占用53端口:但是其实默认安装的CentOS几乎都有这个 ...

  2. LAMP 1.4 PHP编译安装问题解决

    环境:centos X64 最小化安装 php版本:php-5.4.3 安装前.先安装些软件和库文件 yum install -y gcc gcc-c++ make zlib zlib-devel p ...

  3. 串口发送Hex数组

    void MainWindow::String2Hex(QString str, QByteArray &senddata) { int hexdata,lowhexdata; ; int l ...

  4. [转载][效率工具推荐]Mathpix – 将图片数学公式转换为 LaTeX

    转自小众软件:Mathpix – 将图片数学公式转换为 LaTeX Mathpix 是一款跨平台(Windows.macOS.Linux)的 OCR 工具,它能够识别复杂的数学公式,并将其转换为 La ...

  5. Material使用07 MdGridListModule的使用

    1 MatGridListModule简介 对相似数据的展现,尤其是像是图片的展示 使用起来很像表格 官方文档:点击前往 2 MatGridListModule提供的指令 2.1 mat-grid-l ...

  6. 2、misa统计SRR结果

    参考: https://www.sogou.com/link?url=hedJjaC291NYNxVe4xgB4c3bUxXRMqZrT93cntTAgYfyBbRAdP9kIA.. https:// ...

  7. 15、Linux 文件属性和测试( chgrp,chown,chmod和-e -f -d -s

    一.更改文件属性 1.chgrp:更改文件属组 语法: chgrp [-R] 属组名文件名 参数选项 -R:递归更改文件属组,就是在更改某个目录文件的属组时,如果加上-R的参数,那么该目录下的所有文件 ...

  8. 9、IPA通路分析相关网页教程

    IPA FAQ: http://ingenuity.force.com/ipa/IPATutorials# ####有各种相关教程和帮助文件. IPA 分析结果展示: http://www.lucid ...

  9. CF1041F Ray in the tube

    挂上Chester大神的解题报告 有一个思维跳跃的地方,就是不应该枚举所有的$B$点,而是应该在选定一个$A$点之后枚举距离计算. 然后我们发现枚举距离是$2^k$的长度就可以了,证明如下: 假如距离 ...

  10. 会过vip怎么赚钱?大学生,宝妈创业圈子

    会过vip怎么赚钱?是骗局吗1.如果说会过Vip不赚钱,那么一定是我们的没有时间去真心的热爱她:如果你对她如果你对它抱着一颗平和的心,认真的去分享,认真的去听一些前辈的经验,赚钱真的不是难事:2.如果 ...