Oracle 數據類型


一、Number型

Number類型是oralce的數值類型,存儲的數值的精度可以達到38位。Number是一種變長類型,長度為0-22字節。取值范圍為:10^(-130) —— 10^126(不包括)。以十進制格式進行存儲的,它便於存儲,但是在計算上,系統會自動的將它轉換成為二進制進行運算的。
  語法:
  Number(p,s):
  p和s都是可選的。
  p指精度(precision),即總位數。默認情況下精度為38。精度的取值范圍為1~38。
  s指小數位(scale),小數點右邊的位數。小數點位數的合法值為-84~127。小數位的默認值由精度來決定。如果沒有指定精度,小數位默認為最大的取值區間。如果指定了精度,沒有指定小數位。小數位默認為0(即沒有小數位)。
  精度和小數位不會影響數據如何存儲,只會影響允許哪些數值及數值如何舍入。

 

二、varchar2、nvarchar2與char類型

VARCHAR2數據類型的最大長度問題,是一個讓人迷惑的問題,因為VARCHAR2既分PL/SQL Data Types中的變量類型,也分Oracle Database中的字段類型。簡單的說,要看你在什么應用場景下,否則難以回答VARCHAR2數據類型的最大長度問題。

oracle數據庫字段類型

關於Oracle Database中的字段的VARCHAR2類型的最大長度,我們先看下面的例子:

SQL> create table test ( name varchar2(4001) );
create table test ( name varchar2(4001) )
                                  *
ERROR at line 1:
ORA-00910: specified length too long for its datatype
 
 
SQL> create table test ( name varchar2(4000) ); 
 
Table created.

clip_image001

如上所示,在Oracle Database中,VARCHAR2字段類型,最大值為4000,SQL參考手冊中也明確指出VARCHAR2的最大大小為4000,注意此處的最大長度是指字節長度,而不是指字符個數。這個跟參數NLS_LENGTH_SEMANTICS有一定關系,如下所示,當參數NLS_LENGTH_SEMANTICS為字節時,定義的變量長度為字節長度

如下所示,本數據庫NLS_CHARACTERSET值為AL32UTF8,一個漢字占三個字節

SQL> ALTER SESSION SET NLS_LENGTH_SEMANTICS=BYTE; 
 
Session altered 
 
SQL> DROP TABLE TEST PURGE; 
 
Table dropped 
 
SQL> CREATE TABLE TEST ( NAME VARCHAR2(7)); 
 
Table created 
 
SQL> INSERT INTO TEST VALUES ('字'); 
 
1 row inserted 
 
SQL> COMMIT; 
 
Commit complete 
 
SQL> INSERT INTO TEST VALUES('字字字'); 
 
INSERT INTO TEST VALUES('字字字') 
 
ORA-12899: value too large for column "SYSTEM"."TEST"."NAME" (actual: 9, maximum: 7) 
 
SQL> SELECT LENGTH(NAME), LENGTHB(NAME) FROM TEST; 
 
LENGTH(NAME) LENGTHB(NAME) 
 
------------ ------------- 
 
1 3 
 

如果將參數NLS_LENGTH_SEMANTICS,則定義VARCHAR2(7)表示

SQL> ALTER SESSION SET NLS_LENGTH_SEMANTICS=CHAR; 
 
Session altered 
 
SQL> DROP TABLE TEST; 
 
Table dropped 
 
SQL> CREATE TABLE TEST ( NAME VARCHAR2(7)); 
 
Table created 
 
SQL> INSERT INTO TEST VALUES ('字'); 
 
1 row inserted 
 
SQL> COMMIT; 
 
Commit complete 
 
SQL> INSERT INTO TEST VALUES('字字字'); 
 
1 row inserted 
 
SQL> COMMIT; 
 
Commit complete 
 
SQL> SELECT LENGTH(NAME), LENGTHB(NAME) FROM TEST; 
 
LENGTH(NAME) LENGTHB(NAME) 
 
------------ ------------- 
 
1                 3 
 
3                 9 
 

不管參數NLS_LENGTH_SEMANTICS取值為字符或字節,其所能容納的字符串的字節數都不能超過4000.

 

 

oracle中有三種比較常用的類型:varchar2(byte)、varchar2(char)、nvarchar2()。

那么這三種類型到底有什么區別呢?

首先,我們要時刻記清:無論是varchar2還是nvarchar2,最大字節數都是4000

ALTER SESSION SET NLS_LENGTH_SEMANTICS= byte | char;

varchar2(byte):就是默認的表示方式,比如我們寫成:varchar2(100),就相當於varchar2(100 byte),表示最大字節數是100,該字段最多能容納100個字節,強調空間大小。

由於我們描述的是字節,因此,保存漢字等字符時,就要小心了。如果你的數據庫用的是GBK編碼,那么一個漢字將占用2個字節,最多能存50個漢字,如果你的數據庫用的是UTF8編碼,那么一個漢字將占用3個字節,最多能存33個漢字。

varchar2(char):表示最大字符數是100,該字段最多能容納100個字符,強調個數。假設我們寫成varchar2(100char),那么無論是數字、字母、漢字,都看成一個字符,最多寫100個,當然,漢字越多,占用的空間越大,同樣遵循上邊的數據庫編碼原則。例如:存入一個漢字,底層占2或3個字節,存入一個字母,占1個字節,絕對不是某些文章所說1個字母或數字也占2或3個字節!

nvarchar2():沒有byte、char之分,類似於varchar2(char),只不過nvarchar2()屏蔽了數據庫編碼,無論是何種編碼,nvarchar2()中一個漢字都占兩個字節。

一般的教程,也就到這了,可是如果再多一步思考,會發現一個致命問題。

實際應用中,很可能會出現這種寫法:varchar2(1400char),我們主觀的認為,這個字段最長不能超過1400個字符,這意味着我們可能會存入1399個字符,貌似很正確的樣子。

但是,如果這1399個字符都是漢字,字符長度並沒有超過1400,看起來一切正常,但實際上我們損失了一部分數據,為什么?

因為1399個漢字,按UTF8編碼來說(99%的項目都是UTF8編碼吧。。),需要占用1399*3=4197個字節,而文章開篇就說,無論是什么char,最大長度就是4000字節,一個也不能多,因此多出來的197個字節,都會抹去,而整個過程中,無任何錯誤提示,你的數據就這樣蒸發了!

所以,對於GBK編碼的數據庫而言,安全的寫法為:varchar2(2000 char)、nvarchar2(2000),對於UTF8編碼的數據庫而言,安全的寫法為:varchar2(1333char)、nvarchar2(2000)。

 

 

PL/SQL變量類型:

接下來我們看看PL/SQL中VARCHAR2變量類型,如下官方文檔所示,它的最大字節長度為32767,所能容納的字符個數取決於字符集。

 

Declaring Variables for Multibyte Characters

The maximum size of a CHAR or VARCHAR2 variable is 32,767 bytes, whether you specify the maximum size in characters or bytes. The maximum number of characters in the variable depends on the character set type and sometimes on the characters themselves:

Character Set Type

Maximum Number of Characters

Single-byte character set

32,767

n-byte fixed-width multibyte character set (for example, AL16UTF16)

FLOOR(32,767/n)

n-byte variable-width multibyte character set with character widths between 1 and n bytes (for example, JA16SJIS or AL32UTF8)

Depends on characters themselves—can be anything from 32,767 (for a string containing only 1-byte characters) through FLOOR(32,767/n) (for a string containing only n-byte characters).

 

 

 

When declaring a CHAR or VARCHAR2 variable, to ensure that it can always hold n characters in anymultibyte character set, declare its length in characters—that is, CHAR(n CHAR) or VARCHAR2(n CHAR), where n does not exceed FLOOR(32767/4) = 8191.

可以通過下面一個PL/SQL代碼來驗證一下,如下所示,可以定義一個VARCHAR2類型的變量,給其賦值6000個字符串。

 
DECLARE
    V_OUT VARCHAR2(32767);
BEGIN
     V_OUT := RPAD('T', 6000, 'M');
     DBMS_OUTPUT.PUT_LINE(LENGTH(V_OUT));
END;

如果給VARCHAR2類型變量賦值超過23767,就會報PLS-00215: String length constraints must be in range (1 .. 32767)錯誤。

DECLARE
    V_OUT VARCHAR2(32768);
BEGIN
     V_OUT := RPAD('T', 5000, 'M');
     DBMS_OUTPUT.PUT_LINE(LENGTH(V_OUT));
END;

clip_image002

三、Int類型

啊擦

 

 

部分整理自:

https://blog.csdn.net/feipeng21c/article/details/77853116


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM