The error you are encountering, java.lang.ArithmeticException: Decimal precision 45 exceeds max precision 38" occurs because Spark automatically infers the schema for the Oracle NUMBER type. When the data has a very large precision, such as 35 digits in your case, Spark may overestimate the precision due to how it handles floating-point and decimal values.
To explain the issue further:
- Oracle's NUMBER data type is highly flexible and can store values with a very large precision.
- However, Spark's Decimal type has a maximum precision of 38, which limits the number of digits it can accurately represent.
According to the documentation, Spark's decimal data type can have a precision of up to 38, and the scale can also be up to 38 (but must be less than or equal to the precision).
To resolve this issue, you should ensure that your Oracle database does not have values larger than the maximum precision and scale allowed by Spark. You can verify this by running the following query in Oracle:
SELECT MAX(LENGTH(large_number)) FROM example_table
If the result is greater than 38, you can try using the following query to read the data as a string instead of a decimal data type:
SELECT TO_CHAR(large_number) AS large_number FROM example_table.
Spark Schema :
>>> df=spark.read.format("jdbc").option("url", oracle_url).option("query", "SELECT TO_CHAR(large_number) as large_number FROM example_table_with_decimal").option("user", "user1").option("password", "password").option("driver", "oracle.jdbc.driver.OracleDriver").load()
>>> df.printSchema()
root
|-- LARGE_NUMBER: string (nullable = true)
>>>
>>>
>>>
>>>
>>> df=spark.read.format("jdbc").option("url", oracle_url).option("query", "SELECT large_number FROM example_table_with_decimal").option("user", "user1").option("password", "password").option("driver", "oracle.jdbc.driver.OracleDriver").load()
>>>
>>>
>>>
>>> df.printSchema()
root
|-- LARGE_NUMBER: decimal(35,5) (nullable = true)
>>>