数据库的 2个参数 NLS_LENGTH_SEMANTICS 说明,comment 说明
###############
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: able_comment.sql;
SELECT 'comment on table ' || t.table_name || ' is ''' || t.comments ||''';' FROM user_tab_comments t;
spool off;
--導入表的注釋
@ C: able_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 说明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 键盘keydown值表
- 下一篇: (已解决)阿里云部署项目 阿里大于短信功