隐式转换的发生条件
当源数据的类型和目标数据的类型不同的时候,如果没有转换函数,就会发生隐式转换,也称自动转换。当然,有些情况下有些类型是不可以发生转换的,比如说从DATE类型转换到NUMBER类型就会报错。
隐式转换的问题
第一, 隐式转换的最大问题就是转换时会导致索引的无效,进而可能导致全表扫描。当表的数据量很大的时候,产生会很大的性能问题。比如说,VARCHAR2和NVARCHAR2隐式数据类型转换导致的性能问题:
http://www.oracleonlinux.cn/2012/07/varchar_nvarchar_implicit_change_data_type/
第二, 由于隐式转换使得数据库编程人员和DBA难以了解到究竟发生了怎样的类型转换,而且如果代码很多很长的话要查出错误就需要费很大的劲。比如说,每一个函数都有输入参数,如果函数的输入数据的数据类型跟函数的输入参数要求的数据类型不同的话,就会发生隐式转换,如果这两种类型之间不能转换的话就会报错。由于其错误发生得相当隐蔽,查找起来也相当麻烦。
问题的解决
第一:使用转换函数,也就是显式转换。
每一种数据类型都有一组专门针对该类型数据进行处理的函数。如TO_CHAR,TO_CLOB等。其中,最常用的有三个,也就是数值类型、字符类型和日期类型数据之间的转换。如下:
TO_CHAR:把DATE或NUMBER转换成字符串;
TO_DATE:把NUMBER、CHAR或VARCHAR2转换成DATE。当用到时间戳时,可以用到TO_TIMESTAMP或TO_TIMESTAMP_TZ。
TO_NUMBER: 把CHAR或VARCHAR2转换成NUMBER。这里需要注意的是,不能把DATE类型转换成NUMBER类型;
第二:避免隐式转换。
在数据库设计的时候,最好遵循“数据是什么类型,就把它设计成什么类型的”的原则,比如说,不要可以把日期类型的数据设计成字符型。
还有一个原则就是,在相对安全的地方使用函数,比如说对数值使用串处理函数,而不对串使用算术运算函数。
另外,为了方便以后对程序进行检查,最好在适当的地方标注出数据类型的自动转换。
对于Oracle的数据类型,可以参考下面的文章: