Oracle数据库下不可Count的字段类型

雪影工作室版权所有,转载请注明【http://blog.csdn.net/lina791211】

一、问题产生

        在做项目开发的过程中,需要抽取指定数据库的所有表的基本信息(字段个数、comment、行数、第一次DDL时间、最后更新时间等)、每张表的每个字段的基本信息(字段类型、数据量、非空数据量、长度等)。

        问题在计算字段的非空数据量的时候产生了,在count一个类型为clob型的字段的时候报“获得‘-’ 实际是‘clob’” 的警告。

        见下图:


图一 无法count的提示

二、原因分析

        第一次得到这个问题,百思不得其解,后来查询了下Oracle字段的类型后,慢慢明白了点。下面展示一下Oracle中字段的基本属性。(下述字段类型可能不全,请脑补)

Oracle字段类型
字段类型 描述 字段长度及其缺省值
CHAR (size )   用于保存定长(size)字节的字符串数据。 每行定长(不足部分补为空格);最大长度为每行2000字节,缺省值为每行1字节。设置长度(size)前需考虑字符集为单字节或多字节。
VARCHAR2 (size )  用于保存变长的字符串数据。其中最大字节长度由(size)指定。 每行长度可变,最大长度为每行4000字节。设置长度(size)前需考虑字符集为单字节或多字节。
NCHAR(size ) 由字符集决定保存的是定长(size)的字符或字节。 每行定长(不足部分补为空格)。 对固定宽度的字符集来说,长度(size)是指字符的个数,对变宽的字符集来说,长度(size)是指字节的个数。最大长度(size)取决于保存在一个字符中的字节的长度,每行的最大长度为2000字节。由字符集决定缺省值为1个字符或1个字节。
NVARCHAR2 (size ) 由字符集决定保存变长的字符或字节。其中最大长度由(size)指定。 每行变长。对固定宽度的字符集来说,长度(size)是指字符的个数,对变宽的字符集来说,长度(size)是指字节的个数。最大长度(size)取决于保存在一个字符中的字节的长度,每行的最大长度为4000字节。由字符集决定缺省值为1个字符或1个字节。
LONG  保存变长的字符串数据。 在表中每行的长度可变,最大长度为每行231 - 1字节或2G。
UMBER (p, s ) 保存变长的数字。其中精度的最大值为p,和/或有效的数字位数s的最大值38。 每行变长。每行的最大长度为21字节。
DATE  保存定长的日期或时间数据,范围为公元前4712/01/01到公元9999/12/31。 每行固定为7字节长度,缺省值的日期描述(例如DD-MON-YY)由NLS_DATE_FORMAT参数设置。
RAW (size )  保存变长的二进制数据。最大长度由size指定。  在表中每行的长度可变,最大长度为每行2000字节。
LONG RAW  保存变长的二进制数据。 在表中每行的长度可变,最大长度为每行231 - 1字节或2G。
BLOB  保存二进制数据。 最大长度为232 - 1字节或4G。
CLOB  保存单字节字符数据。  最大长度为232 - 1字节或4G。
NCLOB 保存由字符集指定的单字节或固定宽度多字节或变宽多字节的字符数据。 最大长度为232 - 1字节或4G。
BFILE  保存在外部文件的二进制数据。 最大长度为232 - 1字节或4G。
 XML Type XMLType的列将存储一个字符LOB列中的XML文档。有许多内置的功能可以使你从文档中抽取单个节点,还可以在XML Type文档中对任何节点创建索引。 最大长度为232 - 1字节或4G。
     
     
     
     
     

        写到这里,我想大多数做数据库开发的朋友们就大概知道了,为什么有些类型的字段无法count了。上述类型中,LONG、LONG RAW、BLOB、CLOB、NCLOB、BFILE、XMLTYPE这几种属性,数据存储大容量数据的类型。Oracle数据库count字段的时候,先判定此字段是否为NULL,如果不为NULL则加1。(这个为什么不能count我也不太好解释,但是下面的可以解释一下)

        如果计算这个字段的非重复字段的话,Oracle需要读取大批数据进行频繁比较,但是系统内存开销无法支撑(例如有1000条100M的数据进行非重复计算,Oracle如果要实现的话,那么将耗费大量时间和内存,更别说Oracle动辄上万条数据的操作)

        

三、结语

        上面是我的一点阐述,鉴于学识浅薄,了解不多,上述阐释只作为一个参考,无法推断正确性,请广大DBA进行批判。

        另外,在项目中我是直接绕过他们的count的。

if (
	(rs.getString("data_type").indexOf("LONG") < 0) &&		//Long类型字段Oracle都不计算
	(rs.getString("data_type").indexOf("LOB") < 0)	&&		//clob、blob类型字段怎么计算
			。。。
	(rs.getString("data_type").indexOf("XMLTYPE") < 0)		//xmltype类型字段想计算也难
										
) {。。。}







你可能感兴趣的:(oracle,count,字段类型)