Oracle 10g:CLOB数据长度是否可以小于4000?

Oracle 10g:CLOB数据长度是否可以小于4000?,oracle,oracle10g,types,clob,Oracle,Oracle10g,Types,Clob,我们有三个数据库:dev、staging和production。我们在开发环境中进行所有的编码。然后,我们将所有代码和数据库更改推送到staging,以便客户机可以看到它在实时环境中的工作方式。在他们签字后,我们将最终部署到生产环境 现在,关于这些CLOB列:当使用desc和/或查询dev数据库的all_tab_columns视图时,CLOB显示的数据长度为4000。但是,在临时数据库和生产数据库中,与dev等效的CLOB列的数据长度是奇数,如86。我已经寻找了每一个可能的解决办法来解释这是如何

我们有三个数据库:dev、staging和production。我们在开发环境中进行所有的编码。然后,我们将所有代码和数据库更改推送到staging,以便客户机可以看到它在实时环境中的工作方式。在他们签字后,我们将最终部署到生产环境

现在,关于这些CLOB列:当使用desc和/或查询dev数据库的all_tab_columns视图时,CLOB显示的数据长度为4000。但是,在临时数据库和生产数据库中,与dev等效的CLOB列的数据长度是奇数,如86。我已经寻找了每一个可能的解决办法来解释这是如何发生的。我甚至尝试添加一个新的CLOB(86)专栏,认为它可以像VARCHAR2一样工作,但Oracle只是抛出了一个错误


DBA会把事情搞砸吗?这有什么好担心的吗?任何事情似乎都不会因此而中断,但我只是希望元数据在所有环境中都是相同的。

首先,作为一名dba,我对您和dba之间缺乏合作感到遗憾。我们都需要合作才能成功。Clob数据长度可以小于4000字节

create table z ( a number, b clob);
Table created.
insert into z values (1, 'boe');

1 row created.
exec dbms_stats.gather_table_stats (ownname => 'ronr', tabname => 'z');

PL/SQL procedure successfully completed.
select owner, avg_row_len from dba_tables where table_name = 'Z'
SQL> /

OWNER                  AVG_ROW_LEN
------------------------------ -----------
RONR                       109

select length(b) from z;

 LENGTH(B)
----------
     3

您在哪里发现clob长度不能小于4000?

clob没有指定的长度。当您查询所有_选项卡_列时,例如:

select table_name, column_name, data_length
from all_tab_columns
where data_type = 'CLOB';
您会注意到数据长度始终为4000,但这应该被忽略


CLOB的最小大小为零(0),最大大小为8 TB到128 TB,具体取决于数据库块大小。

正如ik_zelf和Jeffrey Kemp指出的,CLOB可以存储少于4000字节的数据

SQL> create table t (clob_in_table clob
  2     , clob_out_of_table clob
  3  ) lob (clob_out_of_table) store as (disable storage in row)
  4     , lob (clob_in_table) store as (enable storage in row)
  5  /

Table created.

SQL> select table_name, column_name, data_length
  2  from user_tab_columns
  3  where table_name = 'T'
  4  /

TABLE_NAME                     COLUMN_NAME                    DATA_LENGTH
------------------------------ ------------------------------ -----------
T                              CLOB_IN_TABLE                         4000
T                              CLOB_OUT_OF_TABLE                       86
但为什么CLOB数据长度不总是4000?这个数字实际上并没有限制CLOB,但您担心元数据被删除可能是对的 不同的服务器。您可能希望在所有服务器上的对象上运行DBMS_METADATA.GET_DDL并比较结果

通过向索引组织的表中添加CLOB,我能够创建较低的数据长度

create table test
(
    column1 number,
    column2 clob,
    constraint test_pk primary key (column1)
)
organization index;

select data_length from user_tab_cols
where table_name = 'TEST' and column_name = 'COLUMN2';
在10.2.0.1.0中,结果为116。
在11.2.0.1.0中,结果为476

这些数字对我来说毫无意义,我猜这是一个错误。但我对不同的存储选项没有很好的理解,也许我只是缺少了一些东西


有人知道这里到底发生了什么吗?

DATA#u LENGTH存储一个列在行中占用的最大字节数。如果CLOB可以在行中存储,则最大值为4000。LOB占用的空间永远不会超过4000字节。如果禁用了行内存储,则LOB将只存储查找LOB数据所需的指针信息,该数据远小于4000字节

SQL> create table t (clob_in_table clob
  2     , clob_out_of_table clob
  3  ) lob (clob_out_of_table) store as (disable storage in row)
  4     , lob (clob_in_table) store as (enable storage in row)
  5  /

Table created.

SQL> select table_name, column_name, data_length
  2  from user_tab_columns
  3  where table_name = 'T'
  4  /

TABLE_NAME                     COLUMN_NAME                    DATA_LENGTH
------------------------------ ------------------------------ -----------
T                              CLOB_IN_TABLE                         4000
T                              CLOB_OUT_OF_TABLE                       86
编辑、添加*\u LOBS视图上的信息

使用[DBA | ALL | USER]_LOBS视图查看定义的行外存储设置:

SQL> select table_name
  2     , cast(substr(column_name, 1, 30) as varchar2(30))
  3     , in_row
  4  from user_lobs
  5  where table_name = 'T'
  6  /

TABLE_NAME                     CAST(SUBSTR(COLUMN_NAME,1,30)A IN_
------------------------------ ------------------------------ ---
T                              CLOB_IN_TABLE                  YES
T                              CLOB_OUT_OF_TABLE              NO
编辑2,一些参考资料

有关定义LOB存储的更多信息,请参见中的,特别是第三条说明可以更改的内容:

注意:

只能修改某些存储参数。比如你 可以使用
更改表。。。修改LOB
语句以更改保留,
PCTVERSION
CACHE
无缓存日志记录
无日志记录
,以及
存储器
条款

您还可以使用ALTER TABLE更改表空间。。。 移动语句

但是,一旦创建了表,就不能更改块 大小,或启用或禁用行内存储设置

还有,他说:

默认情况下,在索引组织的表中创建的没有溢出段的所有LOB都将存储在行外。换句话说,如果创建索引组织的表时没有溢出段,则该表中的LOB将其默认存储属性设置为DISABLE storage In ROW。如果强制尝试为此类LOB指定ENABLE STORAGE IN ROW子句,则SQL将引发错误


这解释了为什么jonearles在索引组织的表中创建LOB时,在data_length列中没有看到4000

这个数据库的版本是相同的吗?我不知道,但我只能假设它们是相同的。我在登台和生产环境中无法访问与在dev中相同的内容,因此我不知道如何在不询问dba(我不想与dba交谈)的情况下说出这些内容。我有什么看法可以问出来吗?赏金是用来解释小于4000的数字到底意味着什么。谢谢你的赏金,先生。这已经困扰我好几个月了。我希望有人能给出一个答案,这样我就可以结束这件事了。这是10g R2,顺便说一句,10.2.0.4.0。不知道为什么索引组织的表的数据长度更长。我会在有时间的时候阅读更多关于表内/表外存储的内容,但是为什么不同数据库的元数据不同呢?开发人员对dev数据库进行数据库修改。然后,我们在月底将脚本交给DBA,让他们在生产中运行。我们的脚本将是
createtablewhatever(clobrow-clob)
,它在dev中显示了预期的4000个数据长度。DBA是否在生产环境中运行该脚本之前对其进行了修改,以便将其存储在表外?@oscilatingcretin:我无法找到为什么在没有不同的
create table
语句的情况下,LOB存储特性会有所不同。或者对于某些存储特性,发出
alter table
语句。我对您的环境了解不够,无法知道如何运行不同的脚本。当然,DBA审查所有脚本并“改进”它们将是一种方法。另一种方法是变更管理中的问题,在变更管理中,开发人员后来用错误的脚本重新构建。