驗證ORACLE不同字符集中漢字佔用的byte及NLS_LENGTH_SEMANTICS引數的影響
官方文件中關於NLS_LENGTH_SEMANTICS引數介紹:
可選值是BYTE | CHAR,預設是BYTE,可以在資料庫和會話級動態修改。也可以在客戶端環境變數中進行設定(不適合JDBC瘦客戶端)
NCHAR, NVARCHAR2, CLOB, and NCLOB 始終是基於BYTE。
以SYS使用者登陸時不考慮NLS_LENGTH_SEMANTICS引數統一使用BYTE;除非在建立物件等DDL語句中明確定義。
ORACLE強烈建議不能在資料庫例項級別設定此引數。
----
AL32UTF8字符集時一個漢字佔三個byte
ZHS16GBK字符集時一個漢字佔兩個byte
本實驗結論:
1.建立表時指定欄位型別為 varchar2(10)時--即不指定使用的型別,欄位使用的dba_tab_columns檢視的char_used欄位值等於建立表時會話級的nls_length_semantics=BYTE
2.在AL32UTF8字符集時一個漢字是3個BYTE,ZHS16GBK字符集時一個漢字佔兩個byte。
3.如果欄位型別為 varchar2(10)為BYTE(dba_tab_columns檢視char_used欄位是B(BYTE)),能存放三個漢字--->一個漢字是3個BYTE
4.如果欄位型別為 varchar2(10)為char(dba_tab_columns檢視char_used欄位是C(CHAR)),能存放十個漢字--->一個漢字是3個BYTE
5.以SYS使用者登陸時不考慮NLS_LENGTH_SEMANTICS引數統一使用BYTE;除非在建立物件等DDL語句中明確定義。
6.在系統或會話級修改nls_length_semantics=char引數值,不會對已有表中varchar2欄位的char_used進行修改
實驗的步驟:
實驗1-4使用AL32UTF8的資料庫進行測試。
實驗1:預設nls_length_semantics=BYTE且指定欄位型別為 varchar2(10)
此時從dba_tab_columns檢視的char_used欄位可以發現使用的是B(BYTE),在AL32UTF8字符集下一個漢字是3個BYTE。
實驗2:修改nls_length_semantics=CHAR且指定欄位型別為 varchar2(10)
此時從dba_tab_columns檢視的char_used欄位可以發現使用的是C(CHAR),此時可以插入10個字元。
實驗3:alter system set nls_length_semantics=char;引數不會對已有的表中varchar2欄位的char_used進行修改
實驗4:測試以SYS使用者登陸時不考慮NLS_LENGTH_SEMANTICS引數統一使用BYTE;除非在建立物件等DDL語句中明確定義。
實驗5:測試ZHS16GBK字符集時一個漢字佔的字元數
具體實驗過程
#################################################################
實驗1:
預設nls_length_semantics=BYTE且指定欄位型別為 varchar2(10)
此時從dba_tab_columns檢視的char_used欄位可以發現使用的是B(BYTE),在AL32UTF8字符集下一個漢字是3個BYTE。
#####################################################################
實驗2:
修改nls_length_semantics=CHAR且指定欄位型別為 varchar2(10)
此時從dba_tab_columns檢視的char_used欄位可以發現使用的是C(CHAR),此時可以插入10個字元。
實驗3:alter system set nls_length_semantics=char;引數不會對原有的表中varchar2欄位的char_used進行修改
實驗5:測試ZHS16GBK字符集時一個漢字佔的字元數
可選值是BYTE | CHAR,預設是BYTE,可以在資料庫和會話級動態修改。也可以在客戶端環境變數中進行設定(不適合JDBC瘦客戶端)
NCHAR, NVARCHAR2, CLOB, and NCLOB 始終是基於BYTE。
以SYS使用者登陸時不考慮NLS_LENGTH_SEMANTICS引數統一使用BYTE;除非在建立物件等DDL語句中明確定義。
ORACLE強烈建議不能在資料庫例項級別設定此引數。
----
AL32UTF8字符集時一個漢字佔三個byte
ZHS16GBK字符集時一個漢字佔兩個byte
本實驗結論:
1.建立表時指定欄位型別為 varchar2(10)時--即不指定使用的型別,欄位使用的dba_tab_columns檢視的char_used欄位值等於建立表時會話級的nls_length_semantics=BYTE
2.在AL32UTF8字符集時一個漢字是3個BYTE,ZHS16GBK字符集時一個漢字佔兩個byte。
3.如果欄位型別為 varchar2(10)為BYTE(dba_tab_columns檢視char_used欄位是B(BYTE)),能存放三個漢字--->一個漢字是3個BYTE
4.如果欄位型別為 varchar2(10)為char(dba_tab_columns檢視char_used欄位是C(CHAR)),能存放十個漢字--->一個漢字是3個BYTE
5.以SYS使用者登陸時不考慮NLS_LENGTH_SEMANTICS引數統一使用BYTE;除非在建立物件等DDL語句中明確定義。
6.在系統或會話級修改nls_length_semantics=char引數值,不會對已有表中varchar2欄位的char_used進行修改
實驗的步驟:
實驗1-4使用AL32UTF8的資料庫進行測試。
實驗1:預設nls_length_semantics=BYTE且指定欄位型別為 varchar2(10)
此時從dba_tab_columns檢視的char_used欄位可以發現使用的是B(BYTE),在AL32UTF8字符集下一個漢字是3個BYTE。
實驗2:修改nls_length_semantics=CHAR且指定欄位型別為 varchar2(10)
此時從dba_tab_columns檢視的char_used欄位可以發現使用的是C(CHAR),此時可以插入10個字元。
實驗3:alter system set nls_length_semantics=char;引數不會對已有的表中varchar2欄位的char_used進行修改
實驗4:測試以SYS使用者登陸時不考慮NLS_LENGTH_SEMANTICS引數統一使用BYTE;除非在建立物件等DDL語句中明確定義。
實驗5:測試ZHS16GBK字符集時一個漢字佔的字元數
具體實驗過程
#################################################################
實驗1:
預設nls_length_semantics=BYTE且指定欄位型別為 varchar2(10)
此時從dba_tab_columns檢視的char_used欄位可以發現使用的是B(BYTE),在AL32UTF8字符集下一個漢字是3個BYTE。
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.AL32UTF8
SQL> select lengthb('白') from dual;
LENGTHB('白')
-------------
3
SQL> show user
USER is "BYS"
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_length_semantics string BYTE
SQL> create table t1(id number,name varchar2(10));
Table created.
SQL> create table t4(id number,name varchar2(10 char));
Table created.
SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name='T1' or table_name='T4' ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
------------------------------ ------------------------------ ---------- -
T4 NAME VARCHAR2 C
T4 ID NUMBER
T1 NAME VARCHAR2 B
T1 ID NUMBER
SQL> desc t1
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(10)
在SQL*PLUS視窗輸入時--經過了字元轉換(猜測是主機的)顯示是5個漢字30個字元
SQL> insert into t1 values(1,'浙江省杭州');
insert into t1 values(1,'浙江省杭州')
*
ERROR at line 1:
ORA-12899: value too large for column "BYS"."T1"."NAME" (actual: 30, maximum: 10)
SQL> insert into t1 values(1,'浙江杭州');
在PL/SQL DEVELOPER工具視窗:
SQL> insert into t1 values(1,'浙江省杭州');
insert into t1 values(1,'浙江省杭州')
ORA-12899: 列 "BYS"."T1"."NAME" 的值太大 (實際值: 15, 最大值: 10)
SQL> insert into t1 values(1,'浙江杭州');
insert into t1 values(1,'浙江杭州')
ORA-12899: 列 "BYS"."T1"."NAME" 的值太大 (實際值: 12, 最大值: 10)
SQL> insert into t1 values(1,'浙江省');
1 row inserted
SQL> commit;
Commit complete
SQL> select * from t1;
ID NAME
---------- ----------
1 浙江省
SQL> insert into t4 values(1,'浙江省杭州市西湖區西湖');
insert into t4 values(1,'浙江省杭州市西湖區西湖')
ORA-12899: 列 "BYS"."T4"."NAME" 的值太大 (實際值: 11, 最大值: 10)
SQL> insert into t4 values(1,'浙江省杭州市西湖區西');
1 row inserted
SQL> commit;
Commit complete
SQL> select * from t4;
ID NAME
---------- ----------------------------------------
1 浙江省杭州
1 浙江省杭州市西湖區西
#####################################################################
實驗2:
修改nls_length_semantics=CHAR且指定欄位型別為 varchar2(10)
此時從dba_tab_columns檢視的char_used欄位可以發現使用的是C(CHAR),此時可以插入10個字元。
SQL> alter session set nls_length_semantics=CHAR;
Session altered.
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_length_semantics string CHAR
SQL> create table t2(id number,name varchar2(10));
Table created.
SQL> create table t3(id number,name varchar2(10 char));
Table created.
SQL> create table t6(id number,name varchar2(10 byte));
Table created.
SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name='T3' or table_name='T2' or table_name='T6' ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
------------------------------ ------------------------------ ---------- -
T6 NAME VARCHAR2 B
T6 ID NUMBER
T3 NAME VARCHAR2 C
T3 ID NUMBER
T2 NAME VARCHAR2 C
T2 ID NUMBER
在PL/SQL DEVELOPER工具視窗:
SQL> insert into t2 values(1,'浙江省杭州市江乾區下沙');
insert into t2 values(1,'浙江省杭州市江乾區下沙')
ORA-12899: 列 "BYS"."T2"."NAME" 的值太大 (實際值: 11, 最大值: 10)
SQL> insert into t2 values(1,'浙江省杭州市江乾區下');
1 row inserted
SQL> insert into t2 values(1,'浙江省杭州市江乾區');
1 row inserted
SQL> commit;
Commit complete
SQL> select * from t2;
ID NAME
---------- ----------------------------------------
1 浙江省杭州市江乾區下
1 浙江省杭州市江乾區
################################################################實驗3:alter system set nls_length_semantics=char;引數不會對原有的表中varchar2欄位的char_used進行修改
SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name='T1' or table_name='T4' ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
------------------------------ ------------------------------ ---------- -
T4 NAME VARCHAR2 C
T4 ID NUMBER
T1 NAME VARCHAR2 B
T1 ID NUMBER
SQL> alter system set nls_length_semantics=char;
System altered.
SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name='T1' or table_name='T4' ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
------------------------------ ------------------------------ ---------- -
T1 ID NUMBER
T1 NAME VARCHAR2 B
T4 ID NUMBER
T4 NAME VARCHAR2 C
此時對T1進行插入操作,超過3個漢字會報錯
SQL> insert into t1 values(11,'浙江省美');
insert into t1 values(11,'浙江省美')
ORA-12899: value too large for column "BYS"."T1"."NAME" (actual: 12, maximum: 10)
實驗4:測試以SYS使用者登陸時不考慮NLS_LENGTH_SEMANTICS引數統一使用BYTE;除非在建立物件等DDL語句中明確定義。
SQL> show user
USER is "SYS"
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_length_semantics string BYTE
SQL> SQL> alter system set nls_length_semantics=char;
System altered.
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_length_semantics string CHAR
SQL> create table bys.t8(id number,name varchar2(10));
Table created.
SQL> create table bys.t9(id number,name varchar2(10 char));
Table created.
SQL> col data_type for a10
set linesize 160
SQL> SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name='T8' or table_name='T9' ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
------------------------------ ------------------------------ ---------- -
T8 ID NUMBER
T8 NAME VARCHAR2 B
T9 ID NUMBER
T9 NAME VARCHAR2 C
##########################################################實驗5:測試ZHS16GBK字符集時一個漢字佔的字元數
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK
SQL> show user
USER is "BYS"
SQL> show parameter nls_length_semantics;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_length_semantics string BYTE
SQL> create table t1(id number,name varchar2(8));
Table created.
SQL> create table t2(id number,name varchar2(8 char));
Table created.
SQL> select table_name,column_name,data_type,char_used from dba_tab_columns where table_name='T1' or table_name='T2' ;
TABLE_NAME COLUMN_NAME DATA_TYPE C
------------------------------ ------------------------------ ---------- -
T2 NAME VARCHAR2 C
T2 ID NUMBER
T1 NAME VARCHAR2 B
T1 ID NUMBER
SQL> select lengthb('白') from dual;
LENGTHB('白')
-------------
2
SQL> insert into t1 values(1,'浙江省杭州');
insert into t1 values(1,'浙江省杭州')
ORA-12899: 列 "BYS"."T1"."NAME" 的值太大 (實際值: 10, 最大值: 8)
SQL> insert into t1 values(1,'浙江杭州');
1 row inserted
SQL> insert into t2 values(1,'浙江省杭州市西湖區');
insert into t2 values(1,'浙江省杭州市西湖區')
ORA-12899: 列 "BYS"."T2"."NAME" 的值太大 (實際值: 9, 最大值: 8)
SQL> insert into t2 values(1,'浙江省杭州市西湖');
1 row inserted
SQL> commit;
Commit complete
SQL> select * from t1;
ID NAME
---------- --------
1 浙江杭州
SQL> select * from t2;
ID NAME
---------- ----------------
1 浙江省杭州市西湖
相關文章
- 【附錄】 字符集(一) 漢字在oracle中佔用位元組數Oracle
- Oracle中文漢字佔用位元組Oracle
- 各平臺影響oracle Process數的引數(轉)Oracle
- 用4種不同的程式設計模式驗證繫結引數程式設計設計模式
- Oracle exp中compress引數的影響測試Oracle
- PHP算式驗證碼和漢字驗證碼的實現方法PHP
- 用C#生成中文漢字驗證碼的基本原理C#
- 最影響Oracle系統效能的初始化引數(zt)Oracle
- JVM 引數調整對 sortx 的影響JVM
- Java教程:影響MySQL效能的配置引數JavaMySql
- 字元編碼及空白漢字佔位符字元
- 驗證資料壓縮對DML的影響
- Libra:數字貨幣的原理、影響、機遇及挑戰
- 用C#生成隨機中文漢字驗證碼的基本原理C#隨機
- Oracle Lob型別相關引數以及效能影響Oracle型別
- 影響企業數字化應用效果的八大因素
- 驗證字串是否包含英文字元、數字或者漢字程式碼例項字串字元
- JAVA——一個漢字佔用多少位元組?Java
- 從數字鴻溝到數字貧困:負面影響及改進策略
- 字符集例子-同一字元不同字符集編碼不同及匯入匯出的亂碼字元
- Laravel 引數驗證的疑與惑Laravel
- js驗證數字JS
- oracle sql去掉漢字保留數字或字母OracleSQL
- 透過實驗詳解CLUSTER_INTERCONNECTS引數對例項的影響
- 通過實驗詳解CLUSTER_INTERCONNECTS引數對例項的影響
- oracle 一欄位 資料存在數字和漢字,只提取數字的sqlOracleSQL
- table_open_cache引數對mysql效能的影響MySql
- ASP中函式呼叫對引數的影響 (轉)函式
- 資料應用的變與不變,ShardingSphere 正在影響未來數字體驗的建設理念
- 簡單的數字驗證碼破解
- oracle 字符集亂碼本質驗證Oracle
- 引數修改影響 sql version_countSQL
- ThinkPHP 類似 AOP 思想的引數驗證PHP
- 【實驗】Oracle的serializable隔離性級別影響Oracle
- oracle實驗記錄 (predicate對cpu cost的影響)Oracle
- html 空白漢字佔位符HTML
- Kafka之acks引數對訊息持久化的影響Kafka持久化
- JPEG的量化引數QP如何影響壓縮質量