一般来说,一个表达式不能包含不同数据类型的值。例如,一个表达式不能5乘以10,然后加上'JAMES'。但是,Oracle支持隐式和显式两种转换值从一种数据类型到另一种数据类型。
隐式和显式数据转换
Oracle建议具体指定显示转换,而不是依赖隐式或自动转换,因为这些原因:
- 使用显式类型转换函数,SQL语句更容易理解。
- 隐式类型转可能会对性能产生负面影响,尤其是如果列值的数据类型被转换为一个常数,而不是其他值。
- 隐式转换依赖于它发生时的上下文,相同的方式在其他情况下可能不生效。例如,datetime值隐式转换为varchar2依赖于NLS_DATE_FORMAT参数的值,可能会返回一个意想不到的年份。
- 隐式转换的算法受Oracle软件版本和Oracle产品的改变而变化,显式转换的行为更容易预测。
隐式数据转换
Oracle数据库会自动转换从一个数据类型的值时,这种转换是有道理的。隐式转换为字符数据类型遵循以下规则:
隐式转换表
CHAR | VARCHAR2 | NCHAR | NVARCHAR2 | DATE | DATETIME/INTERVAL | NUMBER | BINARY_FLOAT | BINARY_DOUBLE | LONG | RAW | ROWID | CLOB | BLOB | NCLOB | |
CHAR | -- | X | X | X | X | X | X | X | X | X | X | -- | X | X | X |
VARCHAR2 | X | -- | X | X | X | X | X | X | X | X | X | X | X | -- | X |
NCHAR | X | X | -- | X | X | X | X | X | X | X | X | X | X | -- | X |
NVARCHAR2 | X | X | X | -- | X | X | X | X | X | X | X | X | X | -- | X |
DATE | X | X | X | X | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
DATETIME/ INTERVAL | X | X | X | X | -- | -- | -- | -- | -- | X | -- | -- | -- | -- | -- |
NUMBER | X | X | X | X | -- | -- | -- | X | X | -- | -- | -- | -- | -- | -- |
BINARY_FLOAT | X | X | X | X | -- | -- | X | -- | X | -- | -- | -- | -- | -- | -- |
BINARY_DOUBLE | X | X | X | X | -- | -- | X | X | -- | -- | -- | -- | -- | -- | -- |
LONG | X | X | X | X | -- | X1 | -- | -- | -- | -- | X | -- | X | -- | X |
RAW | X | X | X | X | -- | -- | -- | -- | -- | X | -- | -- | -- | X | -- |
ROWID | -- | X | X | X | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
CLOB | X | X | X | X | -- | -- | -- | -- | -- | X | -- | -- | -- | -- | X |
BLOB | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | X | -- | -- | -- | -- |
NCLOB | X | X | X | X | -- | -- | -- | -- | -- | X | -- | -- | X | -- | -- |
Note 1: You cannot convert |
Oracle数据库根据以下面的这些规则,进行隐式数据类型转换:
- INSERT 和UPDATE操作时,Oracle把变量值转换成列类型。
- SELECT FROM 操作时,Oracle把列数据类型转换成目标变量类型。
- 字符值和数字值比较时,Oracle把字符值转换成数字值。
- 字符值或数值和浮点数值之间的转换可以是不精确的,因为字符类型和数量使用十进制精度来表示数值,浮点数使用二进制精度。
- 当一个CLOB值转换为一个字符类型如VARCHAR2,或BLOB转换为RAW时。如果要转换的数据大于目标数据类型,那么数据库会返回一个错误。
- 单精度二进制转换为双精度二进制是精确的。
- 双精度二进制转换为单精度二进制是不精确的,如果双精度二进制值的精度位数超出了单精度二进制支持的位数。
- 当字符类型和日期类型比较时,Oracle将字符类型数据转换成日期类型。
- 赋值操作时,Oracle把等号右边的值转换成左边赋值目标数据类型。
- 连接操作时,Oracle把非字符类型转换成字符类型或国家字符类型。
- 在字符类型与非字符类型之间进行算术运算和非算术运算时,Oracle转换任意字符类型为数字、日期或ROWID,要视情况而定。在CHAR/VARCHAR2 和NCHAR/NVARCHAR2之间进行算术运算,Oracle转换为数字。
显式数据转换
可以明确地指使用SQL转换函数转换数据类型,SQL函数显示转换一个数据类型为另一个数据类型:
显式类型转换
to CHAR,VARCHAR2,NCHAR,NVARCHAR2 | to NUMBER | to Datetime/Interval | to RAW | to ROWID | to LONG,LONG RAW | to CLOB, NCLOB,BLOB | to BINARY_FLOAT | to BINARY_DOUBLE | |
from CHAR, VARCHAR2, NCHAR, NVARCHAR2 |
|
|
|
|
|
|
|
|
|
from NUMBER |
|
|
|
|
|
|
|
|
|
from Datetime/ Interval |
|
|
|
|
|
|
|
|
|
from RAW |
|
|
|
|
|
|
|
|
|
from ROWID |
|
|
|
|
|
|
|
|
|
from LONG / LONG RAW |
|
|
|
|
|
|
|
|
|
from CLOB, NCLOB, BLOB |
|
|
|
|
|
|
|
|
|
from CLOB, NCLOB, BLOB |
|
|
|
|
|
|
|
|
|
from BINARY_FLOAT |
|
|
|
|
|
|
|
|
|
from BINARY_DOUBLE |
|
|
|
|
|
|
|
|
|