一同事由於系統需求關系,將SQL SERVER數據庫的一個表導入ORACLE數據庫時,發現居然報錯:ORA-12899: value too large for column xxxx (actual:56, maximum:50),該字段長度在兩個數據庫都是50,之所以出現這個錯誤,原因無外乎兩個:
一:因為ORACLE數據庫它可以存儲字節或字符,例如 CHAR(12 BYTE) CHAR(12 CHAR)的意義是不同的.一般來說默認是存儲字節,你可以查看數據庫參數NLS_LENGTH_SEMANTICS的值。
1: SQL> show parameter nls_length_semantics;
2:
3: NAME TYPE VALUE
4: ------------------------- ----------- -------------
5: nls_length_semantics string BYTE
如果定義為VARCHAR2(50 CHAR),那么該列最多就可以存儲50個漢字,如果定義字段為VARCHAR2(50) 或VARCHAR2(50 BYTE)那么它最多可以存儲多少個漢字就要視數據庫字符集編碼決定。
二:ORACLE數據庫漢字占用幾個字節,要根據ORACLE中字符集編碼決定,一般情況下,數據庫的NLS_CHARACTERSET 為AL32UTF8或UTF8,即一個漢字占用三到四個字節。如果NLS_CHARACTERSET為ZHS16GBK,則一個字符占用兩個字節.
1: SQL> COL PARAMETER FOR A24;
2: SQL> COL VALUE FOR A24
3: SQL> SELECT * FROM v$nls_parameters WHERE PARAMETER='NLS_CHARACTERSET';
4:
5: PARAMETER VALUE
6: ------------------------ ------------------------
7: NLS_CHARACTERSET UTF8
8:
9: SQL>
10:
至於具體情況,可以通過LENGTHB或者VSIZE函數求得是占用字節數。
1: SQL> SELECT LENGTH('您好') FROM DUAL;
2:
3: LENGTH('您好')
4: --------------
5: 2
6:
7: SQL> SELECT LENGTHB('您好') FROM DUAL;
8:
9: LENGTHB('您好')
10: ---------------
11: 6
12:
LENGTH函數求得是占用字符數,LENGTHB或者VSIZE函數求得是占用字節數。
VSIZE returns the number of bytes in the internal representation of expr. If expr is null, then this function returns null.
This function does not support CLOB data directly. However, CLOBs can be passed in as arguments through implicit data conversion.
LENGTH是計算字符的個數,輸入的參數先被轉為字符類型計算
The LENGTH functions return the length of char. LENGTH calculates length using characters as defined by the input character set. LENGTHB uses bytes instead of characters. LENGTHC uses Unicode complete characters. LENGTH2 uses UCS2 code points. LENGTH4 uses UCS4 code points.