【问题标题】:What is the default value of VARCHAR2 in Oracle?Oracle中VARCHAR2的默认值是多少?
【发布时间】:2019-08-20 16:43:51
【问题描述】:

我的一个表中有一个类型为varchar2(2000) 的列,但这是否意味着2000 bytes?或2000 characters?因为我知道字节和字符之间是有区别的……

【问题讨论】:

标签: database oracle varchar2


【解决方案1】:

默认是你会话的NLS参数之一,即NLS_LENGTH_SEMANTICS。以下是我可以从我的会话中检查它的方法:

select value
from   v$nls_parameters
where  parameter = 'NLS_LENGTH_SEMANTICS'
;

VALUE 
------
BYTE

您可以更改会话以更改值(或者您可以通过 SQL Developer 之类的图形界面进行操作)。如果您使用一个 ALTER SESSION 命令,也可以在您的LOGIN.SQL(或全局GLOGIN.SQL)中添加一个,如果您希望在启动会话时分配一个特定值。否则,当您开始一个新会话时,默认值将来自您的 SPFile(很可能)。

以下是我如何检查我的 SPFile 中的内容:

select value
from   v$parameter
where  name = 'nls_length_semantics'
;


VALUE 
------
BYTE

我还可以更改我的系统以更改 SPFile 中的内容,但这是 DBA 的工作(我认为)。无论如何,它是可以改变的。

这类似于其他 NLS 参数 - 以 NLS_DATE_FORMAT 为例,其行为非常相似。

【讨论】:

  • 只是为了确定...当前会话值是否影响现有表的语义?
  • @ÁlvaroGonzález - 不,它没有;并且更改 DB 参数也不会影响现有表。 From the docs: "指定用于 VARCHAR2 和 CHAR 表列、用户定义的对象属性和数据库对象中的 PL/SQL 变量的默认长度语义在会话中创建"
  • @ÁlvaroGonzález - 要理解 Alex Poole 的回答,您可能需要考虑这一点:当 Oracle 将信息写入其字典表时(在这种情况下,无论 USER_TAB_COLUMNS 视图后面的内容),它总是翻译varchar2 列宽到字节。因此,如果您当前的长度语义是CHAR,并且您创建一个列为VARCHAR2(20),并且您当前的字符集是一个四字节字符集(每个字符四个字节),那么 Oracle 将简单地存储该列是80 字节宽。它不会记住您将其声明为 20(CHAR,隐式)。
  • 谢谢。这就是我一直认为理所当然的事情,但这更像是一种直觉,而不是正式的知识:)
【解决方案2】:

除了@mathguy 的回答,如果您有一个现有的表,您可以查询数据字典以查看您看到的大小(大概通过describe 或类似的)是字节还是字符:

create table t (col1 varchar2(2000 byte), col2 varchar2(2000 char));

select column_name, data_type, data_length, char_length, char_used
from user_tab_columns
where table_name = 'T';

COLUMN_NAME DATA_TYPE DATA_LENGTH CHAR_LENGTH CHAR_USED
----------- --------- ----------- ----------- ---------
COL1        VARCHAR2         2000        2000 B
COL2        VARCHAR2         4000        2000 C

其中char_used 是 C 表示字符限制,B 表示字节限制。

data_length 始终以字节为单位,因为这是真正的上限,并且有上限(在我的数据库中为 4000 - 可能是 32k;在 12c+ 中,MAX_STRING_SIZE 设置为 EXTENDED) - 所以即使我'已经说过col2 中允许使用 2000 个字符,如果我使用多字节字符,那么实际上我可能允许少于 2000 个字符,因为总字节数可能会尝试超过 4000。我实际上将 4000 视为数据长度对于声明大于 999 char 的任何内容,因为对于 AL32UTF8,它允许每个字符最多四个字节。

SQL*Plus 等中的describe 命令会显示原始大小,还会显示它是字节还是字符 - 但如果它与会话的NLS_LENGTH_SEMANTICS 设置匹配,则会忽略:

alter session set nls_length_semantics = 'BYTE';

desc t;

Name Null? Type                
---- ----- ------------------- 
COL1       VARCHAR2(2000)      
COL2       VARCHAR2(2000 CHAR) 

alter session set nls_length_semantics = 'CHAR';

desc t;

Name Null? Type                
---- ----- ------------------- 
COL1       VARCHAR2(2000 BYTE) 
COL2       VARCHAR2(2000)      

如果您未在 create 语句中指定 charbyte,该设置也用于默认语义,正如 @mathguy 解释的那样;但与大多数 NLS 设置一样,通常最好 (IMO) 明确声明它,这样就不会对将会发生的事情产生歧义或混淆。

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 1970-01-01
    • 2014-10-20
    • 2018-07-12
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    相关资源
    最近更新 更多