Search code examples
oracle-databaseoracle12c

DBMS_RANDOM.VALUE returned value equals HIGH value


Why does this return values between 1 and 5?

declare
    v numeric;
begin
    v := dbms_random.value(1, 5);
    DBMS_OUTPUT.PUT_LINE(v);
end;

According to the documentation it should return values between 1 and 4.

Note: I am using Oracle 12c Release 2


Solution

  • The documentation says that the numeric data type can (optionally) take scale and precision. Importantly, if you don't specify them, the documentation says this:

    The NUMERIC and DECIMAL datatypes can specify only fixed-point numbers. For those datatypes, the scale (s) defaults to 0.

    https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#SQLRF00213

    You defined your data type as numeric, which Oracle translates to number(38,0) - meaning integer of at most 38 digits (the Oracle limit).

    You generate fractional numbers with RANDOM, but when they are inserted in an integer column (as yours is, by applying the documented defaults) the values are rounded to the closest integer first. So this means that all the values you generate that are between 4.5 and 5.0 get rounded up to the integer 5.

    To fix this, don't add scale and precision to numeric. Instead, get in the habit of using standard Oracle data types - number would be just fine in your case.