Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

rekharaghuram
from rekharaghuram More from this publisher
05.11.2015 Views

CHAPTER 12 ■ DATATYPES 507 NUMBER Type Syntax and Usage The syntax for the NUMBER type is straightforward: NUMBER( p,s ) where P and S are optional and are used to specify the following: • Precision, or the total number of digits. By default, the precision is 38 and has valid values in the range of 1 to 38. The character * may be used to represent 38 as well. • Scale, or the number of digits to the right of the decimal point. Valid values for the scale are –84 to 127, and its default value depends on whether or not the precision is specified. If no precision is specified, then scale defaults to the maximum range. If a precision is specified, then scale defaults to 0 (no digits to the right of the decimal point). So, for example, a column defined as NUMBER stores floating-point numbers (with decimal places), whereas a NUMBER(38) stores only integer data (no decimals), since the scale defaults to 0 in the second case. You should consider the precision and scale to be edits for your data—data integrity tools in a way. The precision and scale do not affect at all how the data is stored on disk, only what values are permitted and how numbers are to be rounded. For example, if a value exceeds the precision permitted, Oracle returns an error: ops$tkyte@ORA10GR1> create table t ( num_col number(5,0) ); Table created. ops$tkyte@ORA10GR1> insert into t (num_col) values ( 12345 ); 1 row created. ops$tkyte@ORA10GR1> insert into t (num_col) values ( 123456 ); insert into t (num_col) values ( 123456 ) * ERROR at line 1: ORA-01438: value larger than specified precision allows for this column So, you can use the precision to enforce some data integrity constraints. In this case, NUM_COL is a column that is not allowed to have more than five digits. The scale, on the other hand, is used to control “rounding” of the number, for example: ops$tkyte@ORA10GR1> create table t ( msg varchar2(10), num_col number(5,2) ); Table created. ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '123.45', 123.45 ); 1 row created. ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '123.456', 123.456 ); 1 row created. ops$tkyte@ORA10GR1> select * from t;

508 CHAPTER 12 ■ DATATYPES MSG NUM_COL ---------- ---------- 123.45 123.45 123.456 123.46 Notice how the number 123.456, with more than five digits, succeeded this time. That is because the scale we used in this example was used to round 123.456 to two digits, resulting in 123.46, and then 123.46 was validated against the precision, found to fit, and inserted. However, if we attempt the following insert, it fails: ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '1234', 1234 ); insert into t (msg,num_col) values ( '1234', 1234 ) * ERROR at line 1: ORA-01438: value larger than specified precision allows for this column because the number 1234.00 has more than five digits in total. When you specify the scale of 2, at most three digits may be to the left of the decimal place and two to the right. Hence, that number does not fit. The NUMBER(5,2) column can hold all values between 999.99 and –999.99. It may seem strange to allow the scale to vary from –84 to 127. What purpose could a negative scale fulfill? It allows you to round values to the left of the decimal place. Just as the NUMBER(5,2) rounded values to the nearest .01, so a NUMBER(5,-2) would round to the nearest 100, for example: ops$tkyte@ORA10GR1> create table t ( msg varchar2(10), num_col number(5,-2) ); Table created. ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '123.45', 123.45 ); 1 row created. ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '123.456', 123.456 ); 1 row created. ops$tkyte@ORA10GR1> select * from t; MSG NUM_COL ---------- ---------- 123.45 100 123.456 100 The numbers were rounded up to the nearest 100. We still have five digits of precision, but there are now seven digits (including the trailing two 0s) permitted to the left of the decimal point: ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '1234567', 1234567 ); 1 row created. ops$tkyte@ORA10GR1> select * from t;

508<br />

CHAPTER 12 ■ DATATYPES<br />

MSG<br />

NUM_COL<br />

---------- ----------<br />

123.45 123.45<br />

123.456 123.46<br />

Notice how the number 123.456, with more than five digits, succeeded this time. That is<br />

because the scale we used in this example was used to round 123.456 to two digits, resulting in<br />

123.46, <strong>and</strong> then 123.46 was validated against the precision, found to fit, <strong>and</strong> inserted. However,<br />

if we attempt the following insert, it fails:<br />

ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '1234', 1234 );<br />

insert into t (msg,num_col) values ( '1234', 1234 )<br />

*<br />

ERROR at line 1:<br />

ORA-01438: value larger than specified precision allows for this column<br />

because the number 1234.00 has more than five digits in total. When you specify the scale of 2,<br />

at most three digits may be to the left of the decimal place <strong>and</strong> two to the right. Hence, that<br />

number does not fit. The NUMBER(5,2) column can hold all values between 999.99 <strong>and</strong> –999.99.<br />

It may seem strange to allow the scale to vary from –84 to 127. What purpose could a negative<br />

scale fulfill? It allows you to round values to the left of the decimal place. Just as the<br />

NUMBER(5,2) rounded values to the nearest .01, so a NUMBER(5,-2) would round to the nearest<br />

100, for example:<br />

ops$tkyte@ORA10GR1> create table t ( msg varchar2(10), num_col number(5,-2) );<br />

Table created.<br />

ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '123.45', 123.45 );<br />

1 row created.<br />

ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '123.456', 123.456 );<br />

1 row created.<br />

ops$tkyte@ORA10GR1> select * from t;<br />

MSG<br />

NUM_COL<br />

---------- ----------<br />

123.45 100<br />

123.456 100<br />

The numbers were rounded up to the nearest 100. We still have five digits of precision, but<br />

there are now seven digits (including the trailing two 0s) permitted to the left of the decimal<br />

point:<br />

ops$tkyte@ORA10GR1> insert into t (msg,num_col) values ( '1234567', 1234567 );<br />

1 row created.<br />

ops$tkyte@ORA10GR1> select * from t;

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!