Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Oleksii.

Asked: July 20, 2016 - 6:38 pm UTC

Last updated: July 22, 2016 - 7:27 am UTC

Version: 12c

Viewed 1000+ times

You Asked

Oracle has several datatypes that can keep numbers. LONGINTEGER can keep the biggest whole number - number in the range of (-2**63) to (2**63)-1
I need to keep bigger numbers so I can't use it.
Keeping the numbers in decimals may affect precision. I need to have this precision so I can't use decimals.

The only way to keep bigger numbers is converting them to string and keeping the strings. But I may lose one more property that I need - assumptions that all rows are sorted. So I can't use something like:
SELECT key_id, data FROM mytable WHERE key_id > 111 FETCH NEXT 100 ROWS ONLY;

Is it possible to use raw data type to keep numbers and have them sorted?

and Connor said...

If you are exceeding the size limits of NUMBER in Oracle, then really you can choose whatever format (string, raw etc) you like because obviously all the numeric computations will be done outside the database anyway.

So some options could be:

varchar2
- which means either left padding at storage or retrieval time to handle sorting

raw
- same issue as above, or you could the bitwise functions to segment out parts of each for sorting (see below)

2 number columns
- one represents high order digits, one represents the low order digits
- sorting is then easy, but retrieval means segmenting input into 2 pieces.

Others welcome to provide suggestions.

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

I'd stick with varchar2

MatteoP, July 21, 2016 - 12:52 pm UTC

At first glance I was for 2 number columns solution, but it becomes tricky when you filter for a range that makes both columns change.
As an example let's assume that datatype limit is 50 but we need to store numbers up to 99; We need a table with a column for units and a column for tens

create table mat_test_tens
(tens number(1), unit number(1));

insert into mat_test_tens
select trunc(level/10), mod(level, 10) from dual connect by level < 100;



If I want records between 19 and 31 I need write a weird query that need to be coded dynamically
select * from mat_test_tens
where case when tens = 1 and unit >= 9 then 1
           when tens = 2  then 1
           when tens = 3 and unit <= 1  then 1
           else 0
      end = 1;


So I would stick with a zero left padded number stored as varchar2

Connor McDonald
July 21, 2016 - 2:25 pm UTC

Good point. Your plans for querying and using the values may force your decision.

Are you sure NUMBER won't meet your needs?

Brian Camire, July 21, 2016 - 7:07 pm UTC

The NUMBER data type can store up to 38 digits of decimal precision, allowing for integers up to 10**38 - 1 (or about 2**126). Is that enough to meet your needs?
Chris Saxon
July 22, 2016 - 7:27 am UTC

Presumably not, but only the OP can answer that!

keys and/or data?

Chuck Jolley, July 21, 2016 - 8:18 pm UTC

Another advantage of the varchar2 idea if these are data in addition to keys is that there are lots of libraries of math functions for manipulating enormous numbers represented by strings.
Also, as a general rule storage is cheap and complexity is expensive.