I'm working in a project based on oracle db and JPA,
I have realized that a column whose value should be generated using a sequence SEQ_CASO has a precision= 12.
However in the sequence object declared in Oracle db I have found the maximum number is much bigger than a 12 figures number (9999999999999...):
I would like to know what would happen if the records number exceeded a 12 figures number in the db? Would the precision of 12 numbers defined by JPA crush the app or something?
Answering to your main question:
I would like to know what would happen if the records number exceeded a 12 figures number in the db?
Considering the code you quoted was made by reverse engineering, the column is probably defined in Oracle as NUMBER(12,0) (precision 12, scale 0).
That said, when the sequence in your application arrives to the point of generating 13 digit numbers, the Oracle database will return the following error when trying to insert these numbers in your table:
ORA-01438: value larger than specified precision allows for this column
The definition of precision and scale can be tricky in Oracle, especially when they are not explicitly defined (i.e. the col is defined just as NUMBER - no precision or scale specified).
More information about precision and scale:
What is the difference between precision and scale?
What is the default Precision and Scale for a Number in Oracle?
you don't need to define unique,nullable attributes with #Column annotation. When you define #Id annotation then it becomes primary key column which is not null and unique.
Even you don't need to define precision attribute and it works properly without it.
#Id
#SequenceGenerator(name="SEQ_CASO",sequenceName="SEQ_CASO_PK",initialValue=1500000,allocationSize=1)
#GeneratedValue(generator="SEQ_CASO",strategy=GenerationType.Sequence)
#Column("ID")
private long Id;
Related
I am using Oracle 12.x DB and have a column with data type - NUMBER(38, 0) and would be populating this column from a Sequence. But I read the maximum value from a sequence would be 28 precision digits i.e. 10^28 -1 value.
Is there a way to generate a maximum of 38 digits value to populate the column mentioned above?
If Oracle sequence cannot go beyond 28 digits then WHY Oracle supports data type like NUMBER with 38 digits precision??
Thanks.
Yes, the limit of a sequence is 10^28-1. Oracle supports larger numbers because sequences aren't the only things to use the number data type. You'd have to ask Oracle why sequences don't go any higher than that.
How would I calculate or estimate the increased storage difference from increasing the precision on a column from number(2,0) to number(6,0)? Or is it the same? No difference? Let's pretend I have 1 million rows in the table. What does the arithmetic look like?
The precision of a number field is basically just a constraint on how much precision Oracle will retain when storing a value. The underlying number format is actually the same (it's a varying-width field, and not something like a fixed-sized integer or float) - the amount of space required is related to the number of digits in the specific numbers which are being stored.
So if you don't modify the values in the table, then the size shouldn't change. But if you increase the precision and then update the table with values with more digits, then they will potentially consume more space.
oracle DB is storing values as NUMBER, which from my understanding is max precision and scale. However hive documentation states that if you set DECIMAL with no precision or scale you will get DECIMAL(10,0) doc. What would the correct HIVE datatype be to accommodate ORACLE NUMBER.
Since Oracle allows any precision/scale for a NUMBER datatype, safest is to store it as Hive STRING, to avoid any kind of data loss.
depending on actual data/or it's usage, downstream can convert it to needed datatype.
According to Oracle docs:
NUMBER:
INT when the scale is 0 and the precision is less than 10
BIGINT when the scale is 0 and the precision is less than 19
DECIMAL when the scale is greater than 0 or the precision is greater
than 19
Is there any way to preserve number precision (0.100 vs 0.1) in Oracle? The precision needs to be stored for accountability reasons.
I want to avoid storing these numbers as a string because there is also a set of stored procedures which do some number crunching on these values.
No. The numbers 0.100, 0.1, and .1 are all identical from Oracle's perspective. They'll all have identical internal representations.
If you need to store the precision, you'll need a second column to store the precision. Or you'll need to store the number in a VARCHAR2 column and convert it to a number before doing the number crunching. Of course, you'll need to define the rules for handling precision in your number crunching logic. If you add 0.100 and 0.22, for example, is the result 0.32 or 0.320?
I would suggest storing both the numeric value for queries and mathematical operations, and the string version "as entered" for audit purposes.
I would suggest if the use case only requires the additional digits to be displayed then convert it to a string as the last step before sending the data to the report:
SELECT
TO_CHAR(column_name, 999.999)
FROM
table_name;
Is there any benefit to specifying the precision on the PK? Is 7,0 sufficient, given that there will probably never be more than a few thousand records?
Any dangers to not specifying the precision?
NUMBER(7, 0) just constrains the domain of values.
Their internal represenations do not differ:
CREATE TABLE t_pk (col1 NUMBER(7, 0) NOT NULL, col2 NUMBER(38) NOT NULL)
INSERT
INTO t_pk
VALUES (9999999, 9999999)
SELECT DUMP(col1), DUMP(col2)
FROM t_pk
DUMP(col1) DUMP(col2)
--- ---
Typ=2 Len=5: 196,10,100,100,100 Typ=2 Len=5: 196,10,100,100,100
In Oracle, the NUMBERs are stored as centesimal digits of the numeric value normalized to 0.01 <= N < 1 and prepended with the exponent.
In the example above:
196 is the 192-based exponent (4).
10 is decimal 9
100's are decimal 99's
The whole number reads in decimal as 00.09 99 99 99 * (100 ^ 4) = 9,999,999
The more digits are required to satisfy the precision requested, the more of them will be stored of course.
When you insert a precise value into a less precise column, it just gets rounded to column's precision and is stored rounded.
Therefore, it is safe performance-wise to declare you column NUMBER(38), since it implies no overhead over NUMBER(7, 0) (for the numbers that fit both types).
However, if your PRIMARY KEYs are integer by nature, you better specify precision as 0 to make sure no fractional value ever gets to your table.
Update:
#Mac also pointed that the clients may rely on the column datatype to figure out the values domain.
If your application expects an INT32, you should make your number a NUMBER(9) or below (or whatever type your client considers to be convertable to Int32).
On the database side of the problem, I have nothing to add to Quassnoi's answer.
But it is worth noting that it may as well have an impact on applications that access the database (or, to be more accurate, on the developers of these applications). In .NET for instance, if you get an IDataRecord including your primary key (using ODP .NET), a call to GetInt32 will miserably fail when your column is defined as NUMBER(38) and succeed when defined as NUMBER(7) (even when when the value is in the correct range).
If you're not expecting more than, say 100K records in the table, if you specify the PK with N(7,0) you'll get an early warning if some runaway process ends up overflowing the PK. If you specified it with N(38) the warning will not appear so early, perhaps.
I'd always err on the side of constraining sizes to the smallest expected for the "life of the product", with a reasonable margin for error.