究竟什么意味着VARCHAR2字段的大小被声明为1 BYTE? (进入Oracle DB)

时间:2015-06-16 10:29:48

标签: sql database oracle rdbms varchar

我不是database,我有以下疑问。

我知道我可以使用它可以包含的字符数来声明 varchar2 字段。

但是在我正在处理的Oracle数据库中,我发现一个字段(名为PDF)被定义为:

VARCHAR2(1 BYTE)

究竟意味着什么?它包含了多少人?

另一个疑问是: VARCHAR 字段和 VARCHAR2 字段之间究竟有什么区别?

TNX

4 个答案:

答案 0 :(得分:19)

您可以将列/变量声明为varchar2(n CHAR)和varchar2(n byte)。

n CHAR表示变量将包含n个字符。在多字节字符集中,您并不总是知道要存储多少字节,但是您确实想要保存一定数量的字符。

n个字节仅表示要存储的字节数。

varchar已弃用。不要使用它。 What is the difference between varchar and varchar2?

答案 1 :(得分:7)

我不知道VARCHARVARCHAR2之间的确切区别,但答案很简单:请勿使用VARCHAR,仅使用VARCHAR2

如果您的数据库使用单字节字符集(例如US7ASCIIWE8MSWIN1252WE8ISO8859P1)运行,那么无论您使用VARCHAR2(x BYTE)还是{{}},都不会有任何区别{1}}。

当您的数据库在多字节字符集上运行时(例如VARCHAR2(x CHAR)AL32UTF8),这只会有所不同。您可以在此示例中看到它:

AL16UTF16

CREATE TABLE my_table ( VARCHAR2_byte VARCHAR2(1 BYTE), VARCHAR2_char VARCHAR2(1 CHAR) ); INSERT INTO my_table (VARCHAR2_char) VALUES ('€'); 1 row created. INSERT INTO my_table (VARCHAR2_char) VALUES ('ü'); 1 row created. INSERT INTO my_table (VARCHAR2_byte) VALUES ('€'); INSERT INTO my_table (VARCHAR2_byte) VALUES ('€') Error at line 10 ORA-12899: value too large for column "MY_TABLE"."VARCHAR2_BYTE" (actual: 3, maximum: 1) INSERT INTO my_table (VARCHAR2_byte) VALUES ('ü') Error at line 11 ORA-12899: value too large for column "MY_TABLE"."VARCHAR2_BYTE" (actual: 2, maximum: 1) 表示无论有多少字节,您最多可以存储1个字符。在Unicode的情况下,一个字符最多可占用4个字节。

VARCHAR2(1 CHAR)表示您可以存储占用最多的角色。 1个字节。

如果您未指定VARCHAR2(1 BYTE)BYTE,则默认值取自CHAR会话参数。

除非您拥有Oracle 12c,否则您可以设置NLS_LENGTH_SEMANTICS限制为MAX_STRING_SIZE=EXTENDED

但是VARCHAR2(4000 CHAR)并不意味着您可以保证最多可存储4000个字符。限制仍然是4000 字节,因此在最坏的情况下,您可以在此类字段中仅存储最多1000个字符。

请参阅此示例(UTF-8中的VARCHAR2(4000 CHAR)占用3个字节):

另见Examples and limits of BYTE and CHAR semantics usage (NLS_LENGTH_SEMANTICS) (Doc ID 144808.1)

答案 2 :(得分:5)

回答第一个问题:
是的,这意味着1个字节分配给1个字符。看看这个例子

varchar2

回答你的下一个: varcharVARCHAR之间的差异:

  1. 2000 bytes最多可存储VARCHAR2个字符,而4000 bytes最多可存储VARCHAR个字符。
  2. 如果我们将数据类型声明为NULL values,那么它将占用VARCHAR2的空间,如果是not数据类型,SELECT DISTINCT ParagraphID , STUFF(( SELECT N' | ' + CAST([LoginName] AS VARCHAR(255)) FROM [dbo].[CM_Signature] f2 WHERE f1.ParagraphID = f2.ParagraphID FOR XML PATH ('')), 1, 1, '') AS FileNameString FROM [dbo].[CM_Signature] f1 将占用任何空格。

答案 3 :(得分:2)

这意味着每个字符只能分配一个字节 - 所以如果您使用多字节字符集,那么您的1个字符将不适合

如果您知道必须至少有足够的空间容纳1个字符,请不要使用BYTE语法,除非您确切知道存储该字节所需的空间

如有疑问,请使用VARCHAR2(1 CHAR)

同样的问题在这里回答Difference between BYTE and CHAR in column datatypes

此外,在12c中,varchar2的最大值现在是32k,而不是4000.如果需要更多,请使用CLOB

在Oracle中

,不要使用VARCHAR