18.6 Object HousekeepingIn the business of working with objects, you will gain a familiarity with a number of ways of getting information about object types that you have created. These include making direct queries of the data dictionary and using the SQL*Plus "describe" command. Another topic in the "housekeeping" category is how to deal with schema changes after you have already built tables on your object types. As the next section of the chapter explains, there are no easy answers to this question. 18.6.1 Data DictionaryThere are a few new entries in the data dictionary that will be very helpful in managing your object types. The shorthand dictionary term for object types is simply TYPE. Object type definitions and object type bodies are both found in the USER_SOURCE view (or DBA_SOURCE, or ALL_SOURCE), just as package specifications and bodies are. Table 18.4 summarizes the views.
18.6.2 SQL*Plus "Describe" CommandIf you're like me and don't like to type any more than necessary, you'll appreciate a wonderful enhancement that Oracle has provided for the describe command in SQL*Plus. It will report not only the attributes of an object type, but also the methods and their arguments. To illustrate: SQL> desc pet_t Name Null? Type ------------------------------- -------- ---- TAG_NO NUMBER(38) NAME VARCHAR2(60) ANIMAL_TYPE VARCHAR2(30) SEX VARCHAR2(1) PHOTO BINARY FILE LOB VACCINATIONS VACCINATION_LIST_T OWNER REF OF PERSON_T METHOD ------ MEMBER FUNCTION SET_TAG_NO RETURNS PET_T Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- NEW_TAG_NO NUMBER IN METHOD ------ MEMBER FUNCTION SET_PHOTO RETURNS PET_T Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- FILE_LOCATION VARCHAR2 IN MEMBER PROCEDURE PRINT_ME Although the formatting could be improved, this is much easier than SELECTing the equivalent information from the data dictionary. 18.6.3 Schema EvolutionLet's say that you have created an object type and you need to make a change to its definition. What do you do? The answer is that it depends -- on whether you have used the type, and on what type of change you want to make. Precious few modifications are easy; the rest will probably age you prematurely. Consider the implications of where you have used the type:
OK, if you want to add an attribute, you're out of luck. What about methods? Oracle8.0 does include an ALTER TYPE statement that allows you to recompile an object specification or body. It also allows you to add new methods. It is extremely limited, however; it does not allow you to add or remove attributes, nor does it allow you to modify the quantity or datatypes of existing method arguments. The basic syntax is: Form I ALTER TYPE [ BODY ] type_name COMPILE [ SPECIFICATION | BODY ]; which does not solve our problem, or: Form II ALTER TYPE [ BODY ] type_name REPLACE <the entire new type or body definition>; Using Form II, we can, in fact, add an entirely new method to an object type, even if there are dependencies on the type. In the case of changing a method's specification (or deleting a method) in object type Foo_t which is implemented in table foo, you would think that export/import would work, using something like:
But alas, it doesn't work, because when you CREATE OR REPLACE the type, it actually assigns a new OID to the type, and the import fails with IMP-00063 when it sees that the OID is different. Huh? What do you mean, "assigns a new OID to the type?" For reasons apparently having to do with facilitating certain operations in the Oracle Call Interface (OCI), object types themselves have an OID. See for yourself -- you can easily retrieve them from the USER_TYPES data dictionary view. Neither can you "CREATE new_object_table AS SELECT ... FROM old_object_table." Even if you could, the REFs wouldn't match up to the OIDs of the new table. It's even worse if you want to make any serious modifications to an object type and you have a dependency on the type from other types or tables. You cannot drop and recreate a parent object table unless you drop the child object types and object tables first. So maybe you could:
It is not obvious to me how to do the second step in a way that will preserve REFs to the type. The only way I see to do it in a guaranteed fashion is to rely on relational primary and foreign keys for tuple identification. That is, your schema will include not only REFs but also equivalent foreign keys. Then, when your OIDs change because you have rebuilt an object table, you can update all the REFs to that object table using foreign key values. Not a pretty picture. Also, you cannot rename object types (number 4 above); attempting to do so fails with "ORA-03001: unimplemented feature."
Copyright (c) 2000 O'Reilly & Associates. All rights reserved. |
|