Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 10 ■ DATABASE TABLES 411 ops$tkyte@ORA10G> create or replace type address_type 2 as object 3 ( city varchar2(30), 4 street varchar2(30), 5 state varchar2(2), 6 zip number 7 ) 8 / Type created. ops$tkyte@ORA10G> create or replace type person_type 2 as object 3 ( name varchar2(30), 4 dob date, 5 home_address address_type, 6 work_address address_type 7 ) 8 / Type created. ops$tkyte@ORA10G> create table people of person_type 2 / Table created. ops$tkyte@ORA10G> desc people Name Null? Type ---------------------------------------- -------- ---------------------------- NAME VARCHAR2(30) DOB DATE HOME_ADDRESS ADDRESS_TYPE WORK_ADDRESS ADDRESS_TYPE That’s all there is to it. We create some type definitions, and then we can create tables of that type. The table appears to have four columns representing the four attributes of the PERSON_TYPE we created. We are at the point where we can now perform DML on the object table to create and query data: ops$tkyte@ORA10G> insert into people values ( 'Tom', '15-mar-1965', 2 address_type( 'Reston', '123 Main Street', 'Va', '45678' ), 3 address_type( 'Redwood', '1 Oracle Way', 'Ca', '23456' ) ); 1 row created. ops$tkyte@ORA10G> select * from people; NAME DOB HOME_ADDRESS(CITY, S WORK_ADDRESS(CITY, S ----- --------- -------------------- -------------------- Tom 15-MAR-65 ADDRESS_TYPE('Reston ADDRESS_TYPE('Redwoo
412 CHAPTER 10 ■ DATABASE TABLES ', '123 Main Street' d', '1 Oracle Way', , 'Va', 45678) 'Ca', 23456) ops$tkyte@ORA10G> select name, p.home_address.city from people p; NAME HOME_ADDRESS.CITY ----- ------------------------------ Tom Reston We’re starting to see some of the object syntax necessary to deal with object types. For example, in the INSERT statement we had to wrap the HOME_ADDRESS and WORK_ADDRESS with a CAST. We cast the scalar values to be of an ADDRESS_TYPE. Another way of saying this is that we create an ADDRESS_TYPE instance for that row by using the default constructor for the ADDRESS_TYPE object. Now, as far as the external face of the table is concerned, there are four columns in our table. By now, after seeing the hidden magic that took place for the nested tables, we can probably guess that there is something else going on. Oracle stores all object-relational data in plain old relational tables—at the end of the day it is all in rows and columns. If we dig into the “real” data dictionary, we can see what this table really looks like: ops$tkyte@ORA10G> select name, segcollength 2 from sys.col$ 3 where obj# = ( select object_id 4 from user_objects 5 where object_name = 'PEOPLE' ) 6 / NAME SEGCOLLENGTH ------------------------- ------------ SYS_NC_OID$ 16 SYS_NC_ROWINFO$ 1 NAME 30 DOB 7 HOME_ADDRESS 1 SYS_NC00006$ 30 SYS_NC00007$ 30 SYS_NC00008$ 2 SYS_NC00009$ 22 WORK_ADDRESS 1 SYS_NC00011$ 30 SYS_NC00012$ 30 SYS_NC00013$ 2 SYS_NC00014$ 22 14 rows selected. This looks quite different from what DESCRIBE tells us. Apparently, there are 14 columns in this table, not 4. In this case, they are
- Page 405 and 406: 360 CHAPTER 10 ■ DATABASE TABLES
- Page 407 and 408: 362 CHAPTER 10 ■ DATABASE TABLES
- Page 409 and 410: 364 CHAPTER 10 ■ DATABASE TABLES
- Page 411 and 412: 366 CHAPTER 10 ■ DATABASE TABLES
- Page 413 and 414: 368 CHAPTER 10 ■ DATABASE TABLES
- Page 415 and 416: 370 CHAPTER 10 ■ DATABASE TABLES
- Page 417 and 418: 372 CHAPTER 10 ■ DATABASE TABLES
- Page 419 and 420: 374 CHAPTER 10 ■ DATABASE TABLES
- Page 421 and 422: 376 CHAPTER 10 ■ DATABASE TABLES
- Page 423 and 424: 378 CHAPTER 10 ■ DATABASE TABLES
- Page 425 and 426: 380 CHAPTER 10 ■ DATABASE TABLES
- Page 427 and 428: 382 CHAPTER 10 ■ DATABASE TABLES
- Page 429 and 430: 384 CHAPTER 10 ■ DATABASE TABLES
- Page 431 and 432: 386 CHAPTER 10 ■ DATABASE TABLES
- Page 433 and 434: 388 CHAPTER 10 ■ DATABASE TABLES
- Page 435 and 436: 390 CHAPTER 10 ■ DATABASE TABLES
- Page 437 and 438: 392 CHAPTER 10 ■ DATABASE TABLES
- Page 439 and 440: 394 CHAPTER 10 ■ DATABASE TABLES
- Page 441 and 442: 396 CHAPTER 10 ■ DATABASE TABLES
- Page 443 and 444: 398 CHAPTER 10 ■ DATABASE TABLES
- Page 445 and 446: 400 CHAPTER 10 ■ DATABASE TABLES
- Page 447 and 448: 402 CHAPTER 10 ■ DATABASE TABLES
- Page 449 and 450: 404 CHAPTER 10 ■ DATABASE TABLES
- Page 451 and 452: 406 CHAPTER 10 ■ DATABASE TABLES
- Page 453 and 454: 408 CHAPTER 10 ■ DATABASE TABLES
- Page 455: 410 CHAPTER 10 ■ DATABASE TABLES
- Page 459 and 460: 414 CHAPTER 10 ■ DATABASE TABLES
- Page 461 and 462: 416 CHAPTER 10 ■ DATABASE TABLES
- Page 463 and 464: 418 CHAPTER 10 ■ DATABASE TABLES
- Page 466 and 467: CHAPTER 11 ■ ■ ■ Indexes Inde
- Page 468 and 469: CHAPTER 11 ■ INDEXES 423 value of
- Page 470 and 471: CHAPTER 11 ■ INDEXES 425 One of t
- Page 472 and 473: CHAPTER 11 ■ INDEXES 427 We then
- Page 474 and 475: CHAPTER 11 ■ INDEXES 429 we ended
- Page 476 and 477: CHAPTER 11 ■ INDEXES 431 The data
- Page 478 and 479: CHAPTER 11 ■ INDEXES 433 if ( (++
- Page 480 and 481: CHAPTER 11 ■ INDEXES 435 Table 11
- Page 482 and 483: CHAPTER 11 ■ INDEXES 437 When Sho
- Page 484 and 485: CHAPTER 11 ■ INDEXES 439 an 8KB b
- Page 486 and 487: CHAPTER 11 ■ INDEXES 441 select *
- Page 488 and 489: CHAPTER 11 ■ INDEXES 443 select *
- Page 490 and 491: CHAPTER 11 ■ INDEXES 445 Indicate
- Page 492 and 493: CHAPTER 11 ■ INDEXES 447 an index
- Page 494 and 495: CHAPTER 11 ■ INDEXES 449 Table 11
- Page 496 and 497: CHAPTER 11 ■ INDEXES 451 9 1, 'M'
- 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
412<br />
CHAPTER 10 ■ DATABASE TABLES<br />
', '123 Main Street' d', '1 <strong>Oracle</strong> Way',<br />
, 'Va', 45678) 'Ca', 23456)<br />
ops$tkyte@ORA10G> select name, p.home_address.city from people p;<br />
NAME HOME_ADDRESS.CITY<br />
----- ------------------------------<br />
Tom Reston<br />
We’re starting to see some of the object syntax necessary to deal with object types. For<br />
example, in the INSERT statement we had to wrap the HOME_ADDRESS <strong>and</strong> WORK_ADDRESS with a<br />
CAST. We cast the scalar values to be of an ADDRESS_TYPE. Another way of saying this is that<br />
we create an ADDRESS_TYPE instance for that row by using the default constructor for the<br />
ADDRESS_TYPE object.<br />
Now, as far as the external face of the table is concerned, there are four columns in our<br />
table. By now, after seeing the hidden magic that took place for the nested tables, we can<br />
probably guess that there is something else going on. <strong>Oracle</strong> stores all object-relational data<br />
in plain old relational tables—at the end of the day it is all in rows <strong>and</strong> columns. If we dig into<br />
the “real” data dictionary, we can see what this table really looks like:<br />
ops$tkyte@ORA10G> select name, segcollength<br />
2 from sys.col$<br />
3 where obj# = ( select object_id<br />
4 from user_objects<br />
5 where object_name = 'PEOPLE' )<br />
6 /<br />
NAME<br />
SEGCOLLENGTH<br />
------------------------- ------------<br />
SYS_NC_OID$ 16<br />
SYS_NC_ROWINFO$ 1<br />
NAME 30<br />
DOB 7<br />
HOME_ADDRESS 1<br />
SYS_NC00006$ 30<br />
SYS_NC00007$ 30<br />
SYS_NC00008$ 2<br />
SYS_NC00009$ 22<br />
WORK_ADDRESS 1<br />
SYS_NC00011$ 30<br />
SYS_NC00012$ 30<br />
SYS_NC00013$ 2<br />
SYS_NC00014$ 22<br />
14 rows selected.<br />
This looks quite different from what DESCRIBE tells us. Apparently, there are 14 columns in<br />
this table, not 4. In this case, they are