05.11.2015 Views

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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

CHAPTER 12 ■ DATATYPES 509<br />

MSG<br />

NUM_COL<br />

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

123.45 100<br />

123.456 100<br />

1234567 1234600<br />

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

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

*<br />

ERROR at line 1:<br />

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

So, the precision dictates how many digits are permitted in the number after rounding,<br />

using the scale to determine how to round. The precision is an integrity constraint, whereas<br />

the scale is an “edit.”<br />

It is interesting <strong>and</strong> useful to note that the NUMBER type is, in fact, a variable-length<br />

datatype on disk <strong>and</strong> will consume between 0 <strong>and</strong> 22 bytes of storage. Many times, programmers<br />

consider a numeric datatype to be a fixed-length type, as that is what they typically see<br />

when programming with 2- or 4-byte integers <strong>and</strong> 4- or 8-byte floats. The <strong>Oracle</strong> NUMBER type is<br />

similar to a variable-length character string. We can see what happens with numbers that contain<br />

differing amounts of significant digits. We’ll create a table with two NUMBER columns <strong>and</strong><br />

populate the first column with many numbers that have 2, 4, 6, . . . 28 significant digits. Then,<br />

we’ll simply add 1 to each of them:<br />

ops$tkyte@ORA10GR1> create table t ( x number, y number );<br />

Table created.<br />

ops$tkyte@ORA10GR1> insert into t ( x )<br />

2 select to_number(rpad('9',rownum*2,'9'))<br />

3 from all_objects<br />

4 where rownum update t set y = x+1;<br />

14 rows updated.<br />

Now, if we use the built-in VSIZE function that shows how much storage the column takes,<br />

we can review the size differences between the two numbers in each row:<br />

ops$tkyte@ORA10GR1> set numformat 99999999999999999999999999999<br />

ops$tkyte@ORA10GR1> column v1 format 99<br />

ops$tkyte@ORA10GR1> column v2 format 99<br />

ops$tkyte@ORA10GR1> select x, y, vsize(x) v1, vsize(y) v2<br />

2 from t order by x;<br />

X<br />

Y V1 V2<br />

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

99 100 2 2<br />

9999 10000 3 2

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

Saved successfully!

Ooh no, something went wrong!