# Number Type Mapping between Oracle and Ruby

## Default mapping

Oracle numbers in select statements are fetched as followings by default:

Oracle Data Type | Ruby Class |
---|---|

NUMBER(prec) or NUMBER(prec, 0) | Integer |

NUMBER(prec, scale) where prec < 15 and scale != 0 | Float |

NUMBER(prec, scale) where prec >= 15 and scale != 0 | BigDecimal |

FLOAT or FLOAT(prec) | Float |

NUMBER without precision and scale | BigDecimal |

number type returned by functions or calculated number | BigDecimal |

BINARY_FLOAT | Float |

BINARY_DOUBLE | Float |

When the data type is within Integer or Float class, it is fetched as Integer or Float. Otherwise, BigDecimal.

Note that the mapping is determined by the column definition in
select statements, not by the actual value fetched.
For example the column in `select count(*) from table_name`

is
fetched as BigDecimal because it is returned from `count`

function.

The mapping is customizable by `OCI8::BindType::Mapping`

.
The default values of Oracle number data type mapping are:

```
# NUMBER or FLOAT data type, used for the first six rows in the above table
OCI8::BindType::Mapping[:number] = OCI8::BindType::Number
# BINARY_FLOAT data type, used for the seventh row in the above table
OCI8::BindType::Mapping[:binary_float] = OCI8::BindType::BinaryDouble
# BINARY_DOUBLE data type, used for the eighth row in the above table
OCI8::BindType::Mapping[:binary_double] = OCI8::BindType::BinaryDouble
```

`OCI8::BindType::Number`

checks precision and scale to determine
ruby class. The first four rows in the above table are hard-coded.
The fifth and sixth rows are, however, customizable by
`OCI8::BindType::Mapping[:number_no_prec_setting]`

and
`OCI8::BindType::Mapping[:number_unknown_prec]`

respectively.

The default values are:

```
OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::BigDecimal
OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::BigDecimal
```

The mapping may be changed as follows in future.

Oracle Data Type | Ruby Class |
---|---|

NUMBER(prec) or NUMBER(prec, 0) | Integer |

other NUMBER | OraNumber |

BINARY_FLOAT | Float |

BINARY_DOUBLE | Float |

## Customize mapping

Add the following code to fetch all number or float columns as OraNumber.

```
OCI8::BindType::Mapping[:number] = OCI8::BindType::OraNumber
```

Otherwise, add the following code to customize the fifth and sixth rows only in the above table.

```
OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::OraNumber
OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::OraNumber
```

If you want to fetch numbers as Integer or Float by its actual value, use the following code:

```
# Fetch numbers as Integer when their fractional part is zero.
# Otherwise, Float. For example when a column contains 10 and
# 10.1, they are fetched as Integer and Float respectively.
OCI8::BindType::Mapping[:number] = OCI8::BindType::BasicNumberType
```