Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 12 ■ DATATYPES 503 ops$tkyte@ORA10GR1> create table t ( raw_data raw(16) ); Table created. The RAW type is much like the VARCHAR2 type in terms of storage on disk. The RAW type is a variable-length binary string, meaning that the table T just created, for example, may store anywhere from 0 to 16 bytes of binary data. It is not padded out like the CHAR type. When dealing with RAW data, you will likely find it being implicitly converted to a VARCHAR2 type—that is, many tools such as SQL*Plus will not display the RAW data directly, but will convert it to a hexadecimal format for display. In the following example, we create some binary data in our table using SYS_GUID(), a built-in function that returns a 16-byte RAW string that is globally unique (GUID stands for globally unique identifier): ops$tkyte@ORA10GR1> insert into t values ( sys_guid() ); 1 row created. ops$tkyte@ORA10GR1> select * from t; RAW_DATA -------------------------------- FD1EB03D3718077BE030007F01002FF5 You can immediately note two things here. First, the RAW data looks like a character string. That is just how SQL*Plus retrieved and printed it, and that is not how it is stored on disk. SQL*Plus cannot print arbitrary binary data on your screen, as that could have serious side effects on the display. Remember that binary data may include control characters such as a carriage return or linefeed, or maybe a Ctrl+G character that would cause your terminal to “beep.” Second, the RAW data looks much larger than 16 bytes—in fact, in this example, you can see 32 characters. This is due to the fact that every binary byte takes two hexadecimal characters to display. The stored RAW data is really 16 bytes in length, and you can see this using the Oracle DUMP function. Here, I am “dumping” the value of the binary string and using the optional parameter to specify the base that should be used when displaying the value of each byte. I am using base 16, so we can compare the results of dump with the previous string: ops$tkyte@ORA10GR1> select dump(raw_data,16) from t; DUMP(RAW_DATA,16) ------------------------------------------------------------------------------- Typ=23 Len=16: fd,1e,b0,3d,37,18,7,7b,e0,30,0,7f,1,0,2f,f5 So, DUMP shows us this binary string is in fact 16 bytes long (LEN=16) and displays the binary data byte by byte. As we can see, this dump display matches up with the implicit conversion performed when SQL*Plus fetched the RAW data into a string. This implicit conversion goes the other direction as well: ops$tkyte@ORA10GR1> insert into t values ( 'abcdef' ); 1 row created. That did not insert the string abcdef, but rather a 3-byte RAW with the bytes AB, CD, EF, or in decimal with the bytes 171, 205, 239. If you attempt to use a string that does not consist of valid hex characters, you will receive an error message:
504 CHAPTER 12 ■ DATATYPES ops$tkyte@ORA10GR1> insert into t values ( 'abcdefgh' ); insert into t values ( 'abcdefgh' ) * ERROR at line 1: ORA-01465: invalid hex number The RAW type may be indexed and used in predicates—it is as functional as any other datatype. However, you must take care to avoid unwanted implicit conversions, and you must be aware that they will occur. I prefer and recommend using explicit conversions in all cases, which can be performed using the following built-in functions: • HEXTORAW: To convert strings of hexadecimal characters to the RAW type • RAWTOHEX: To convert RAW strings to hexadecimal strings The RAWTOHEX function is invoked implicitly by SQL*Plus when it fetches a RAW type into a string, and the HEXTORAW function is invoked implicitly when inserting the string. It is a good practice to avoid implicit conversions and to always be explicit when coding. So the previous examples could have been written as follows: ops$tkyte@ORA10GR1> select rawtohex(raw_data) from t; RAWTOHEX(RAW_DATA) -------------------------------- FD1EB03D3718077BE030007F01002FF5 ops$tkyte@ORA10GR1> insert into t values ( hextoraw('abcdef') ); 1 row created. Number Types Oracle 10g supports three native datatypes suitable for storing numbers. Oracle9i Release 2 and earlier support exactly one native datatype suitable for storing numeric data. In this list, the NUMBER type is supported by all releases, and the subsequent two types are new datatypes supported only in Oracle 10g and later: • NUMBER: The Oracle NUMBER type is capable of storing numbers with an extremely large degree of precision—38 digits of precision, in fact. The underlying data format is similar to a “packed decimal” representation. The Oracle NUMBER type is a variable-length format from 0 to 22 bytes in length. It is appropriate for storing any number as small as 10e -130 and numbers up to but not including 10e 126 . This is by far the most common NUMBER type in use today. • BINARY_FLOAT: This is an IEEE native single-precision floating-point number. On disk it will consume 5 bytes of storage: 4 fixed bytes for the floating-point number and 1 length byte. It is capable of storing numbers in the range of ~ ± 10 38.53 with 6 digits of precision.
- Page 498 and 499: CHAPTER 11 ■ INDEXES 453 column w
- Page 500 and 501: CHAPTER 11 ■ INDEXES 455 Bitmap j
- Page 502 and 503: CHAPTER 11 ■ INDEXES 457 INSERT a
- Page 504 and 505: CHAPTER 11 ■ INDEXES 459 7 l_last
- Page 506 and 507: CHAPTER 11 ■ INDEXES 461 ops$tkyt
- Page 508 and 509: CHAPTER 11 ■ INDEXES 463 If we co
- Page 510 and 511: CHAPTER 11 ■ INDEXES 465 ops$tkyt
- Page 512 and 513: CHAPTER 11 ■ INDEXES 467 Caveat o
- Page 514 and 515: CHAPTER 11 ■ INDEXES 469 ops$tkyt
- Page 516 and 517: CHAPTER 11 ■ INDEXES 471 Frequent
- Page 518 and 519: CHAPTER 11 ■ INDEXES 473 select *
- Page 520 and 521: CHAPTER 11 ■ INDEXES 475 If you s
- Page 522 and 523: CHAPTER 11 ■ INDEXES 477 we’ll
- Page 524 and 525: CHAPTER 11 ■ INDEXES 479 Predicat
- Page 526 and 527: CHAPTER 11 ■ INDEXES 481 ops$tkyt
- Page 528 and 529: CHAPTER 11 ■ INDEXES 483 ops$tkyt
- Page 530 and 531: CHAPTER 11 ■ INDEXES 485 This dem
- Page 532 and 533: CHAPTER 11 ■ INDEXES 487 SELECT /
- Page 534 and 535: CHAPTER 12 ■ ■ ■ Datatypes Ch
- Page 536 and 537: CHAPTER 12 ■ DATATYPES 491 • TI
- Page 538 and 539: CHAPTER 12 ■ DATATYPES 493 (in th
- Page 540 and 541: CHAPTER 12 ■ DATATYPES 495 That d
- Page 542 and 543: CHAPTER 12 ■ DATATYPES 497 ops$tk
- Page 544 and 545: CHAPTER 12 ■ DATATYPES 499 Table
- Page 546 and 547: CHAPTER 12 ■ DATATYPES 501 The IN
- Page 550 and 551: CHAPTER 12 ■ DATATYPES 505 • BI
- Page 552 and 553: CHAPTER 12 ■ DATATYPES 507 NUMBER
- Page 554 and 555: CHAPTER 12 ■ DATATYPES 509 MSG NU
- Page 556 and 557: CHAPTER 12 ■ DATATYPES 511 They a
- Page 558 and 559: CHAPTER 12 ■ DATATYPES 513 ■Not
- Page 560 and 561: CHAPTER 12 ■ DATATYPES 515 Coping
- Page 562 and 563: CHAPTER 12 ■ DATATYPES 517 Note t
- Page 564 and 565: CHAPTER 12 ■ DATATYPES 519 We are
- Page 566 and 567: CHAPTER 12 ■ DATATYPES 521 Format
- Page 568 and 569: CHAPTER 12 ■ DATATYPES 523 ops$tk
- Page 570 and 571: CHAPTER 12 ■ DATATYPES 525 You ca
- Page 572 and 573: CHAPTER 12 ■ DATATYPES 527 month
- Page 574 and 575: CHAPTER 12 ■ DATATYPES 529 DT2-DT
- Page 576 and 577: CHAPTER 12 ■ DATATYPES 531 DT TS
- Page 578 and 579: CHAPTER 12 ■ DATATYPES 533 ops$tk
- Page 580 and 581: CHAPTER 12 ■ DATATYPES 535 Since
- Page 582 and 583: CHAPTER 12 ■ DATATYPES 537 ops$tk
- Page 584 and 585: CHAPTER 12 ■ DATATYPES 539 ops$tk
- Page 586 and 587: CHAPTER 12 ■ DATATYPES 541 suppor
- Page 588 and 589: CHAPTER 12 ■ DATATYPES 543 Concep
- Page 590 and 591: CHAPTER 12 ■ DATATYPES 545 We can
- Page 592 and 593: CHAPTER 12 ■ DATATYPES 547 buffer
- Page 594 and 595: CHAPTER 12 ■ DATATYPES 549 Note t
- Page 596 and 597: CHAPTER 12 ■ DATATYPES 551 13 dbm
CHAPTER 12 ■ DATATYPES 503<br />
ops$tkyte@ORA10GR1> create table t ( raw_data raw(16) );<br />
Table created.<br />
The RAW type is much like the VARCHAR2 type in terms of storage on disk. The RAW type is a<br />
variable-length binary string, meaning that the table T just created, for example, may store<br />
anywhere from 0 to 16 bytes of binary data. It is not padded out like the CHAR type.<br />
When dealing with RAW data, you will likely find it being implicitly converted to a VARCHAR2<br />
type—that is, many tools such as SQL*Plus will not display the RAW data directly, but will convert<br />
it to a hexadecimal format for display. In the following example, we create some binary<br />
data in our table using SYS_GUID(), a built-in function that returns a 16-byte RAW string that is<br />
globally unique (GUID st<strong>and</strong>s for globally unique identifier):<br />
ops$tkyte@ORA10GR1> insert into t values ( sys_guid() );<br />
1 row created.<br />
ops$tkyte@ORA10GR1> select * from t;<br />
RAW_DATA<br />
--------------------------------<br />
FD1EB03D3718077BE030007F01002FF5<br />
You can immediately note two things here. First, the RAW data looks like a character string.<br />
That is just how SQL*Plus retrieved <strong>and</strong> printed it, <strong>and</strong> that is not how it is stored on disk.<br />
SQL*Plus cannot print arbitrary binary data on your screen, as that could have serious side<br />
effects on the display. Remember that binary data may include control characters such as a<br />
carriage return or linefeed, or maybe a Ctrl+G character that would cause your terminal to<br />
“beep.”<br />
Second, the RAW data looks much larger than 16 bytes—in fact, in this example, you can<br />
see 32 characters. This is due to the fact that every binary byte takes two hexadecimal characters<br />
to display. The stored RAW data is really 16 bytes in length, <strong>and</strong> you can see this using the<br />
<strong>Oracle</strong> DUMP function. Here, I am “dumping” the value of the binary string <strong>and</strong> using the<br />
optional parameter to specify the base that should be used when displaying the value of each<br />
byte. I am using base 16, so we can compare the results of dump with the previous string:<br />
ops$tkyte@ORA10GR1> select dump(raw_data,16) from t;<br />
DUMP(RAW_DATA,16)<br />
-------------------------------------------------------------------------------<br />
Typ=23 Len=16: fd,1e,b0,3d,37,18,7,7b,e0,30,0,7f,1,0,2f,f5<br />
So, DUMP shows us this binary string is in fact 16 bytes long (LEN=16) <strong>and</strong> displays the<br />
binary data byte by byte. As we can see, this dump display matches up with the implicit conversion<br />
performed when SQL*Plus fetched the RAW data into a string. This implicit conversion<br />
goes the other direction as well:<br />
ops$tkyte@ORA10GR1> insert into t values ( 'abcdef' );<br />
1 row created.<br />
That did not insert the string abcdef, but rather a 3-byte RAW with the bytes AB, CD, EF, or<br />
in decimal with the bytes 171, 205, 239. If you attempt to use a string that does not consist of<br />
valid hex characters, you will receive an error message: