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 10 ■ DATABASE TABLES 397 ops$tkyte@ORA10G> SELECT /*+NESTED_TABLE_GET_REFS*/ 2 NESTED_TABLE_ID,SYS_NC_ROWINFO$ 3 FROM "OPS$TKYTE"."EMPS_NT" 4 / NESTED_TABLE_ID SYS_NC_ROWINFO$(EMPNO, EN -------------------------------- ------------------------- F60DEEE0FF7D7BC1E030007F01001321 EMP_TYPE(7782, 'CLARK', ' MANAGER', 7839, '09-JUN-8 1', 2450, 100) F60DEEE0FF7D7BC1E030007F01001321 EMP_TYPE(7839, 'KING', 'P RESIDENT', NULL, '17-NOV- 81', 5000, 100) ... Well, this is somewhat surprising if you describe this table: ops$tkyte@ORA10G> desc emps_nt Name Null? Type ----------------------------- -------- -------------------- EMPNO NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) These two columns don’t even show up. They are part of the hidden implementation of nested tables. The NESTED_TABLE_ID is really a foreign key to the parent table DEPT_AND_EMP. DEPT_AND_EMP actually has a hidden column in it that is used to join to EMPS_NT. The SYS_NC_ ROWINF$ “column” is a magic column; it is more of a function than a column. The nested table here is really an object table (it is made of an object type), and SYS_NC_INFO$ is the internal way Oracle references the row as an object, instead of referencing each of the scalar columns. Under the covers, all Oracle has done for us is implement a parent/child table with systemgenerated primary and foreign keys. If we dig a little deeper, we can query the “real” data dictionary to see all of the columns in the DEPT_AND_EMP table: sys@ORA10G> select name 2 from sys.col$ 3 where obj# = ( select object_id 4 from dba_objects 5 where object_name = 'DEPT_AND_EMP' 6 and owner = 'OPS$TKYTE' ) 7 / NAME ------------------------------ DEPTNO

398 CHAPTER 10 ■ DATABASE TABLES DNAME EMPS LOC SYS_NC0000400005$ Selecting this column out from the nested table, we’ll see something like this: ops$tkyte@ORA10G> select SYS_NC0000400005$ from dept_and_emp; SYS_NC0000400005$ -------------------------------- F60DEEE0FF887BC1E030007F01001321 F60DEEE0FF897BC1E030007F01001321 F60DEEE0FF8A7BC1E030007F01001321 F60DEEE0FF8B7BC1E030007F01001321 The weird-looking column name, SYS_NC0000400005$, is the system-generated key placed into the DEPT_AND_EMP table. If we dig even deeper, we will find that Oracle has placed a unique index on this column. Unfortunately, however, it neglected to index the NESTED_TABLE_ID in EMPS_NT. This column really needs to be indexed, as we are always joining from DEPT_AND_EMP to EMPS_NT. This is an important thing to remember about nested tables if you use them with all of the defaults as just done: always index the NESTED_TABLE_ID in the nested tables! I’ve gotten off track, though, at this point—I was talking about how to treat the nested table as if it were a real table. The NESTED_TABLE_GET_REFS hint does that for us. We can use the hint like this: ops$tkyte@ORA10G> select /*+ nested_table_get_refs */ empno, ename 2 from emps_nt where ename like '%A%'; EMPNO ENAME ---------- ---------- 7782 CLARK 7876 ADAMS 7499 ALLEN 7521 WARD 7654 MARTIN 7698 BLAKE 7900 JAMES 7 rows selected. ops$tkyte@ORA10G> update /*+ nested_table_get_refs */ emps_nt 2 set ename = initcap(ename); 14 rows updated. ops$tkyte@ORA10G> select /*+ nested_table_get_refs */ empno, ename 2 from emps_nt where ename like '%a%';

398<br />

CHAPTER 10 ■ DATABASE TABLES<br />

DNAME<br />

EMPS<br />

LOC<br />

SYS_NC0000400005$<br />

Selecting this column out from the nested table, we’ll see something like this:<br />

ops$tkyte@ORA10G> select SYS_NC0000400005$ from dept_<strong>and</strong>_emp;<br />

SYS_NC0000400005$<br />

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

F60DEEE0FF887BC1E030007F01001321<br />

F60DEEE0FF897BC1E030007F01001321<br />

F60DEEE0FF8A7BC1E030007F01001321<br />

F60DEEE0FF8B7BC1E030007F01001321<br />

The weird-looking column name, SYS_NC0000400005$, is the system-generated key placed<br />

into the DEPT_AND_EMP table. If we dig even deeper, we will find that <strong>Oracle</strong> has placed a unique<br />

index on this column. Unfortunately, however, it neglected to index the NESTED_TABLE_ID in<br />

EMPS_NT. This column really needs to be indexed, as we are always joining from DEPT_AND_EMP<br />

to EMPS_NT. This is an important thing to remember about nested tables if you use them with<br />

all of the defaults as just done: always index the NESTED_TABLE_ID in the nested tables!<br />

I’ve gotten off track, though, at this point—I was talking about how to treat the nested<br />

table as if it were a real table. The NESTED_TABLE_GET_REFS hint does that for us. We can use the<br />

hint like this:<br />

ops$tkyte@ORA10G> select /*+ nested_table_get_refs */ empno, ename<br />

2 from emps_nt where ename like '%A%';<br />

EMPNO ENAME<br />

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

7782 CLARK<br />

7876 ADAMS<br />

7499 ALLEN<br />

7521 WARD<br />

7654 MARTIN<br />

7698 BLAKE<br />

7900 JAMES<br />

7 rows selected.<br />

ops$tkyte@ORA10G> update /*+ nested_table_get_refs */ emps_nt<br />

2 set ename = initcap(ename);<br />

14 rows updated.<br />

ops$tkyte@ORA10G> select /*+ nested_table_get_refs */ empno, ename<br />

2 from emps_nt where ename like '%a%';

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

Saved successfully!

Ooh no, something went wrong!