Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Using VARRAYs and Nest ed Tables                                              Administration TipsUsing VARRAYs and Nested ...
Using VARRAYs and Nest ed Tables                                                Administration TipsSQL> SELECT * FROM EMPL...
Using VARRAYs and Nest ed Tables                                                  Administration TipsSQL> SELECT ADDR(1) F...
Using VARRAYs and Nest ed Tables                                              Administration Tipseffort: 3 elements, each ...
Using VARRAYs and Nest ed Tables                                                     Administration TipsNow the syntax is ...
Using VARRAYs and Nest ed Tables                                                      Administration TipsERROR AT LINE 1:O...
Using VARRAYs and Nest ed Tables                                                Administration TipsAnd likewise, trying to...
Using VARRAYs and Nest ed Tables                                                  Administration TipsUnfortunately (and th...
Upcoming SlideShare
Loading in …5
×

Varraysandnestedtables

883 views

Published on

oracle foreign key primary key constraints performance tuning MTS IOT 9i block size backup rman corrupted column drop rename recovery controlfile backup clone architecture database archives export dump dmp duplicate rows extents segments fragmentation hot cold blobs migration tablespace locally managed redo undo new features rollback ora-1555 shrink free space user password link TNS tnsnames.ora listener java shutdown sequence

  • Be the first to comment

  • Be the first to like this

Varraysandnestedtables

  1. 1. Using VARRAYs and Nest ed Tables Administration TipsUsing VARRAYs and Nested TablesThe VARRAYA VARRAY allows you to store multi-line items as part of a single row within a table. Forexample, you might want to store people’s addresses: usually, these are stored in a tableusing columns such as ‘Address Line 1’, ‘Address Line 2’ and so on. By using a VARRAY, wecan store multiple lines of an address as one entity –in fact as an “object” which is a“collection” of otherwise separate items… hence the term often used for them…‘collection objects’.A VARRAY is so-called because it is a ‘variable array’ of items. It’s variable in the sensethat you get to define how many items it should be comprised of, and you can then use anynumber of items up to that number. But once you’ve reached that number, it suddenlygets a lot less variable: the upper limit is strictly fixed, and can’t be breached.A simple demo might help.SQL> CREATE TYPE ADDRESS AS VARRAY(3) OF VARCHAR2(25); 2 /TYPE CREATED.Notice that we create a “type”, with a user-given name, as an array of UP TO 3 items.Each one of those items (in this case) can be a varchar2 entry up to 25 characters long.SQL> CREATE TABLE EMPLOYEES ( 2 NAME VARCHAR2(15), 3 ADDR ADDRESS);TABLE CREATED.A perfectly ordinary create table statement –except that the data type for the secondcolumn is the address “type” I created just a moment before.SQL> INSERT INTO EMPLOYEES VALUES ( 2 HOWARD ROGERS, 3 ADDRESS (16 BRADEY AVENUE,HAMMONDVILLE,NSW 2170) 4 );1 ROW CREATED.Notice here that to populate the table’s second column, I must reference not the columnname (‘Addr’), but the type name (‘Address’). Here, I’ve used all 3 of my available entries.SQL> COMMIT;COMMIT COMPLETE.Copyright © How ard Rogers 2002 2/24/20 02 Page 1 of 8
  2. 2. Using VARRAYs and Nest ed Tables Administration TipsSQL> SELECT * FROM EMPLOYEES;NAME---------------ADDRHOWARD ROGERSADDRESS(16 BRADEY AVENUE, HAMMONDVILLE, NSW 2170)And here we see that selecting from the table is a perfectly normal operation, with noparticular syntactical tricks. Note, though, that the display includes the type name [i.e.,“ADDRESS(…”], which makes it look almost as if you are applying a function to the data.That means you’ll have to develop ways of stripping the type name out of the returningdata if you’re going to make use of it in your application.What happens if you try to exceed the permitted array length? Well, this:SQL> INSERT INTO EMPLOYEES VALUES ( 2 HOMER SIMPSON, 3 ADDRESS (3216 BRADLEY AVENUE,SOUTH PARK,HAMMONDVILLE,NSW 2170’) 4 );ADDRESS (3216 BRADLEY AVENUE,SOUTH PARK, HAMMONDVILLE,NSW 2170)*ERROR AT LINE 3:ORA-22909: EXCEEDED MAXIMUM VARRAY LIMITCan you index the varray’d column? Let’s see:SQL> CREATE INDEX VARRAY_EMPLOY ON EMPLOYEES (ADDR);CREATE INDEX VARRAY_EMPLOY ON EMPLOYEES (ADDR) *ERROR AT LINE 1:ORA-02327: CANNOT CREATE INDEX ON EXPRESSION WITH DATATYPE NAMED ARRAY TYPESo the answer is no, which means that any access to the arrayed column is extremely likelyto provoke a full table scan. That in turn means that the use of VARRAYs is not somethingyou’d undertake lightly if you were hoping to win some performance awards for yourapplication.Finally, can you reference individual parts of the array? Well, the following ‘global’command works:SQL> SELECT ADDR FROM EMPLOYEES;ADDR-------------------------------------------------------ADDRESS(16 BRADEY AVENUE, HAMMONDVILLE, NSW 2170)…so perhaps something like ‘select addr(1) from employees’ will select just the firstelement of the array?Copyright © How ard Rogers 2002 2/24/20 02 Page 2 of 8
  3. 3. Using VARRAYs and Nest ed Tables Administration TipsSQL> SELECT ADDR(1) FROM EMPLOYEES;SELECT ADDR(1) FROM EMPLOYEES *ERROR AT LINE 1:ORA-00904: INVALID COLUMN NAMEUnfortunately not. In fact, you can’t select a single part of the array –and what’s ratherworse, you can’t update a single part of the array, either. You have to update the entirething, or none of it. If I move house from 16 Bradey Avenue to 15 Bradey Avenue, thecommand has to look like this:SQL> UPDATE EMPLOYEES SET ADDR= 2 ADDRESS (15 BRADEY AVENUE,HAMMONDVILLE,NSW 2170) 3 WHERE NAME=HOWARD ROGERS;In other words, you have to treat the entire thing as a single entity, and minor changes toparts of it nevertheless require you to update all of it. That can lead, of course, to rathera lot of redo and rollback being produced for what would have been, had the (in this case)address been stored as three separate columns, a fairly small update.Are VARRAYs useful, then? Not really. They make selecting just the data from the tabletricky (unless you particularly want to see the TYPE name appear with the data everytime). Updates are expensive. Selects are done via full table scans. And you lose anyability to work with just particular parts of the data… it’s all or nothing.The Nested TableA ‘nested table’ is, in effect, an infinitely variable VARRAY: there’s no pre-defined limit onthe number of elements that can be stored within it, so if you need to add an extraelement, you are free to do so. What’s more, the various components of the nested tablecan be updated and selected on separately (unlike, as we have just seen, the VARRAYwhich is treated as a monolithic whole).As an example, we can repeat our earlier demo, this time using a nested table:SQL> DROP TYPE ADDRESS;TYPE DROPPED.SQL> CREATE TYPE ADDRESS AS OBJECT (HOUSE VARCHAR2(25),STREET VARCHAR2(25), STATE VARCHAR2(25)); 2 /TYPE CREATED.Having first gotten rid of our varray version of the address type, here we are creating atype ADDRESS. In practical effect, this version of the type is much the same as our earlierCopyright © How ard Rogers 2002 2/24/20 02 Page 3 of 8
  4. 4. Using VARRAYs and Nest ed Tables Administration Tipseffort: 3 elements, each of varchar2(25). But note how we have to name and define eachof the elements separately this time, as though they were columns of a table (which is, ineffect, what they are about to become). That gives scope for greater flexibility than avarray: there’s no reason why I couldn’t have used date or number data types for some ofmy ‘columns’, if I’d needed them. The syntax of the varray doesn’t allow this sort ofmixing and matching of data types.SQL> CREATE TYPE ADDR_TABLE AS TABLE OF ADDRESS; 2 /TYPE CREATED.Here, we’re creating an object table type, of the type ‘Address’ just created. It’s thetable type that can be used when we create our relational table:SQL> CREATE TABLE EMPLOYEES ( 2 NAME VARCHAR2(20), 3 ADDR ADDR_TABLE) 4 NESTED TABLE ADDR STORE AS ADDRESSES;TABLE CREATED.As you see, we can finally create an ordinary relational table, but with its second columndefined as having a data type of ‘addr_table’ –which is the table type we created amoment earlier (and which itself, of course, uses the ‘address’ type created initially).Note the last line of the syntax. That must be included so that the addresses we are goingto enter into the employees table get stored in a properly-named table of their own –thenested table. (Failure to include this line, by the way, yields an “ORA-22913: MUSTSPECIFY TABLE NAME FOR NESTED TABLE COLUMN OR ATTRIBUTE” error message). In thisexample, the addresses are going to be stored in a table called “Addresses”.Now, although we’ve just created a table called ‘addresses’, it won’t be listed inUSER_TABLES. Instead, we have to query USER_OBJECT_TABLES to see it. It’s possible todo a ‘describe addresses’ in SQL*Plus, though –at which point, you’ll see that it containsthree columns which are the three elements originally defined for the ‘address’ type (i.e.,HOUSE, STREET and STATE in this example).How do we now get data into this table, and how do we then manipulate it? Well, as ever,some examples might help:SQL> INSERT INTO EMPLOYEES VALUES ( 2 HOWARD ROGERS, 3 ADDR_TABLE( 4 ADDRESS (16 BRADEY AVENUE,HAMMONDVILLE,NSW), 5 ADDRESS (4 JULIUS AVENUE,CHATSWOOD,NSW)) 6 );Copyright © How ard Rogers 2002 2/24/20 02 Page 4 of 8
  5. 5. Using VARRAYs and Nest ed Tables Administration TipsNow the syntax is rather obscure here (and it doesn’t help much when the word ‘address’and all its variants keeps cropping up). If you manage to bear in mind, though, that‘addr_table’ is the data type we declared when creating the employees table, and‘address’ is the object type we created right at the start –then hopefully it’s a littleclearer as to what keywords go where.In particular, note that the actual name of the nested table, “Addresses”, doesn’t appearanywhere in the syntax.So much for getting one row, containing two addresses, into the employees table. Whatabout getting them back again? Well, you could try this:SQL> SELECT * FROM EMPLOYEES;NAME--------------------ADDR(HOUSE, STREET, STATE)---------------------------------------------------------------------HOWARD ROGERSADDR_TABLE(ADDRESS(16 BRADEY AVENUE, HAMMONDVILLE, NSW), ADDRESS(4 JULIUS AVENUE,CHATSWOOD, NSW))…but we’re back to the VARRAY’s problem of pretty disgusting output.Fortunately, this time, we can fix that… but it requires rather cleverer syntax than ye olde‘select * from…’ that we know and love.SQL> SELECT E.NAME,A.HOUSE,A.STREET,A.STATE 2 FROM EMPLOYEES E, TABLE(E.ADDR)(+) A;NAME HOUSE STREET STATE--------------- ------------------------- -------------------- -----HOWARD ROGERS 16 BRADEY AVENUE HAMMONDVILLE NSWHOWARD ROGERS 4 JULIUS AVENUE CHATSWOOD NSWIn fact, what we’ve had to do here is select the three separate elements from the addressobject type as though they were columns from a table for which we have to perform a (left)outer join. Which is all perfectly understandable, I suppose –except that you might haveexpected to use the “Addresses” table name (since that’s what the nested table is actuallycalled, after all). Instead, you use as the table name what was actually supplied as thecolumn name when we defined the employees table.You can see why we usually leave this stuff to the developers!At which point, you are bound to ask: why not just query the ‘Addresses’ table directly?SQL> SELECT * FROM ADDRESSES;SELECT * FROM ADDRESSES *Copyright © How ard Rogers 2002 2/24/20 02 Page 5 of 8
  6. 6. Using VARRAYs and Nest ed Tables Administration TipsERROR AT LINE 1:ORA-22812: CANNOT REFERENCE NESTED TABLE COLUMNS STORAGE TABLE…because you can’t, that’s why!Well, what about updates. The promise was, you’ll remember, that updates to part of theaddress details would now be possible. And it is… but again, the syntax is not exactlyintuitive:SQL> UPDATE TABLE(SELECT ADDR FROM EMPLOYEES WHERE NAME=HOWARD ROGERS) 2 SET HOUSE = 15 BRADEY AVENUE 3 WHERE HOUSE = 16 BRADEY AVENUE;1 ROW UPDATED.In other words, you use an Oracle-supplied function called ‘TABLE’ to turn the nested tablecolumn into something like a real table, to which regular SQL syntax can then be applied.(Somewhat bizarrely, the same function was named “THE” in Oracle 8.0 …we can begrateful for the name-change in 8i!) It certainly does the trick:SQL> SELECT E.NAME,A.HOUSE,A.STREET,A.STATE 2 FROM EMPLOYEES E, TABLE(E.ADDR)(+) A;NAME HOUSE STREET STATE--------------- --------------------- ------------------------- -----HOWARD ROGERS 15 BRADEY AVENUE HAMMONDVILLE NSWHOWARD ROGERS 4 JULIUS AVENUE CHATSWOOD NSWYou use much the same technique for deletes:SQL> DELETE FROM 2 TABLE(SELECT ADDR FROM EMPLOYEES WHERE NAME=HOWARD ROGERS) 3 WHERE STREET = CHATSWOOD;1 ROW DELETED.SQL> SELECT E.NAME,A.HOUSE,A.STREET,A.STATE 2 FROM EMPLOYEES E, TABLE(E.ADDR)(+) A;NAME HOUSE STREET STATE---------------- -------------------- ------------------------- -----HOWARD ROGERS 15 BRADEY AVENUE HAMMONDVILLE NSWOnce again, if you’d thought you could hare off to the ‘Addresses’ table itself and dodirect updates, you’d be in for a surprise:SQL> UPDATE ADDRESSES SET HOUSE=16 BRADEY AVENUE;UPDATE ADDRESSES SET HOUSE=16 BRADEY AVENUE *ERROR AT LINE 1:ORA-22812: CANNOT REFERENCE NESTED TABLE COLUMNS STORAGE TABLECopyright © How ard Rogers 2002 2/24/20 02 Page 6 of 8
  7. 7. Using VARRAYs and Nest ed Tables Administration TipsAnd likewise, trying to do direct deletes produces exactly the same error.Incidentally, and whilst we’re trying to break the entire object-relational parts of Oracle,you’ll get similar errors if you try performing various bits of DDL on the nested tabledirectly:SQL> TRUNCATE TABLE ADDRESSES;TRUNCATE TABLE ADDRESSES *ERROR AT LINE 1:ORA-22812: CANNOT REFERENCE NESTED TABLE COLUMNS STORAGE TABLESQL> DROP TABLE ADDRESSES;DROP TABLE ADDRESSES *ERROR AT LINE 1:ORA-22914: DROP OF NESTED TABLES NOT SUPPORTEDSuch mischief aside, however, it does appear that we have a reasonably flexible thinggoing for us with nested tables. What’s more, we can talk directly to the “Addresses”table when it comes to indexing:SQL> CREATE INDEX BLAH_ADDR ON ADDRESSES(HOUSE);INDEX CREATED.In other words, it is possible to put as many indexes on the nested table as we like, and onas many columns as we wish. Concatenated indexes are OK, too:SQL> CREATE INDEX CONCAT_ADDR ON ADDRESSES(HOUSE,STATE);INDEX CREATED.Having said all of that, nested tables are still potentially a performance dog, and amanage ment nightmare. The trouble arises right back at the beginning, when you createthe ‘employees’ table with the magic clause:… NESTED TABLE ADDR STORE AS ADDRESSES;What that actually does is to create three segments. Of course, you get the employeestable (though you also get an extra column created, which Oracle hides from you, butwhich is visible in SYS.COL$, provided you know your object number). You also get theobject table called addresses. But you also end up with a new index, cunningly namedSYS_Cxxxxxxx. That’s an index, associated with a constraint, on that hidden column in theemployees table. The index is there to help tie the nested table’s rows back to the maintable’s data in as efficient a way as possible (that is, travelling from nested table to itscontainer table is pretty efficient).Copyright © How ard Rogers 2002 2/24/20 02 Page 7 of 8
  8. 8. Using VARRAYs and Nest ed Tables Administration TipsUnfortunately (and this is where the management nightmares start), all three segments arecreated in the one tablespace (the one where the ‘employees’ table is created), andthere’s nothing you can do about that. Of course, this being 8i, there’s nothing to stopyou now going ahead and moving the employees table to a different tablespace, whichleaves behind the nested table and the linking index (ALTER TABLE X MOVE TABLESPACE Y willdo the trick). You could then rebuild the index into yet another tablespace. That wouldget all three segments nicely separated… but it’s a pain to have to remember to do thesethings manually.What’s worse, as things stand, there is no index on the nested table to help speed upnested row retrieval (that is, travelling from the container data to the relevant nesteddata is pretty inefficient –and it’s that direction of travel which is likely to be the onemost frequently used, of course).No worries: you can create your own index (though again, it’s a pain to have to rememberto do so). But the trouble is that the index you need is on a column of the nested tablewhich is yet again one of these hidden columns that seem to crop up all over the place assoon as you start using objects. In fact, the column is called NESTED_TABLE_ID (and isalways so-called, regardless of what your nested table is actually called), so you need toget into the habit of issuing something like this:SQL> CREATE INDEX NEST_ADDR_IDX 2 ON ADDRESSES(NESTED_TABLE_ID);INDEX CREATED.(Be aware, too, that the nested_table_id is the thing that ties nested rows back to theirparent –so, when “Howard Rogers” had two addresses listed in the reports I showed earlier,the id would have been repeated twice. If I’d had 65 addresses, the id would haverepeated 65 times. In other words, the nested_table_id has a lot of repetition –and canthus probably benefit quite a lot from a ‘compress’ attribute… in this example, “compress1” would have been appropriate).The net result of all of this is that, frankly, I can’t see why anyone would want to useNested Tables, just as VARRAYs seem to be a lot of cleverness that causes more troublethan it’s worth. I suppose that in the right circumstances, and with all potentially nastyissues duly thought about and resolved at design time, they might have a use. But I myselfhonestly can’t see what those ‘right circumstances’ would be. It strikes me, instead, thatusing the old relational model (where you create a separate child table for people’s phonenumbers or addresses, and link back to the parent record using old-fashioned referentialintegrity constraints and a couple of good indexes) is simpler, more flexible, and a darnedsight less hassle, administratively.Your mileage might well vary, of course!Copyright © How ard Rogers 2002 2/24/20 02 Page 8 of 8

×