rem rem $Header: o8idemo.sql 11-aug-99.10:58:36 hyeh Exp $ rem rem o8idemo.sql rem rem Copyright (c) 1998, 1999, Oracle Corporation. All rights reserved. rem rem NAME rem o8idemo.sql - Purchase Order example and DDL sample on object view rem rem DESCRIPTION rem This demonstrate the Purchase Order example described in manual rem Application Developer's Guide rem and some extra examples on object view DDL rem rem NOTES rem In order to run this sample, the database must be started up with rem option compatible=8.1.0.0.0 (or a higher compatible value) rem rem MODIFIED (MM/DD/YY) rem mchien 11/04/99 - 8.1.6 additions from KOSINSKI rem hyeh 08/11/99 - set session format rem mjaeger 07/14/99 - bug 808870: OCCS: convert tabs, no long lines rem hyeh 01/06/99 - use compressed nested iot rem hyeh 12/22/98 - do not use compressed index - bug 785326, 785403 rem mkrishna 10/22/98 - add FORCE option for MAKE_REF rem mchien 10/21/98 - do not use compressed index for now - bug 740405 rem yaggarwa 10/13/98 - rem yaggarwa 10/13/98 - Created rem REMARK >>>> Set System Variables For Current SQLPlus Session <<<< SET FEEDBACK 1 SET NUMWIDTH 10 SET PAGESIZE 24 SET LINESIZE 80 SET TRIMSPOOL ON SET TAB OFF SET DEFINE '^' SET ECHO ON CONNECT SYSTEM/MANAGER DROP USER po CASCADE / GRANT RESOURCE,DBA TO po IDENTIFIED BY po / CONNECT po/po CREATE TABLE Customer_reltab ( Custno NUMBER, -- Customer NUMBER Custname VARCHAR2(200), -- Customer name Street VARCHAR2(200), -- Customer Street City VARCHAR2(200), -- Customer City State CHAR(2), Zip VARCHAR2(20), -- Customer Zip Phone1 VARCHAR2(20), Phone2 VARCHAR2(20), Phone3 VARCHAR2(20), PRIMARY KEY (Custno) ) / CREATE TABLE PurchaseOrder_reltab ( PONo NUMBER, -- purchase order no Custno NUMBER references Customer_reltab , -- foreign KEY referencing customer OrderDate DATE, -- Date OF order ShipDate DATE, -- Date to be shipped ToStreet VARCHAR2(200), -- shipto Address ToCity VARCHAR2(200), ToState CHAR(2), ToZip VARCHAR2(20), PRIMARY KEY(PONo) ) / CREATE TABLE Stock_reltab ( StockNo NUMBER PRIMARY KEY, Price NUMBER, TaxRate NUMBER ) / CREATE TABLE LineItems_reltab ( LineItemNo NUMBER, PONo NUMBER references PurchaseOrder_reltab, StockNo NUMBER references Stock_reltab, Quantity NUMBER, Discount NUMBER, PRIMARY KEY (PONo,LineItemNo) ); -- 2. Values Inserted INSERT INTO Customer_reltab VALUES(1,'Jean Nance','2, Avocet Drive','Redwood Shores','CA','95054', '801-010-0090',NULL,NULL); INSERT INTO Customer_reltab VALUES(2,'John Nike','323, College Drive','Edison','NJ','08820', '901-090-0000','908-201-1002',NULL); INSERT INTO PurchaseOrder_reltab VALUES(1001,1,SYSDATE,'10-MAY-1997',NULL,NULL,NULL,NULL); INSERT INTO PurchaseOrder_reltab VALUES(2001,2,SYSDATE,'20-MAY-1997','55, Madison Ave','Madison','WI', '53715'); INSERT INTO Stock_reltab VALUES(1004,6750.00,2); INSERT INTO Stock_reltab VALUES(1011,4500.23,2); INSERT INTO Stock_reltab VALUES(1534,2234.00,2); INSERT INTO Stock_reltab VALUES(1535,3456.23,2); INSERT INTO LineItems_reltab VALUES(01,1001,1534,12,0) / INSERT INTO LineItems_reltab VALUES(02,1001,1535,10,10) / INSERT INTO LineItems_reltab VALUES(10,2001,1004,1,0) / INSERT INTO LineItems_reltab VALUES(11,2001,1011,2,1) / -- 3. Selection :- -- List Customer and Lineitems FOR a given Purchase Order SELECT c.Custno, c.Custname, c.Street, c.City, c.State, c.Zip, c.Phone1, c.Phone2, c.Phone3, p.PONo, p.OrderDate, l.StockNo, l.LineItemNo, l.Quantity, l.Discount FROM Customer_reltab c, PurchaseOrder_reltab p, LineItems_reltab l WHERE c.Custno = p.Custno AND p.PONo = l.PONo AND p.PONo = 1001; -- List the Total value OF Purchase Orders SELECT p.PONo, SUM(s.Price * l.Quantity) FROM PurchaseOrder_reltab p, LineItems_reltab l, Stock_reltab s WHERE p.PONo = l.PONo AND l.StockNo = s.StockNo GROUP BY p.PONo; -- List all the Purchase Order information and the Line Item information -- FOR those LineItems_tab that use the stock WITH StockNo 1004 SELECT p.PONo, p.Custno, l.StockNo, l.LineItemNo, l.Quantity, l.Discount FROM PurchaseOrder_reltab p, LineItems_reltab l WHERE p.PONo = l.PONo (+) AND l.StockNo = 1004 ; -- ======================================================================== -- THE OBJECT-RELATIONAL SYSTEM (Oracle 8.0.3) CREATE TYPE StockItem_objtyp / CREATE TYPE LineItem_objtyp / CREATE TYPE PurchaseOrder_objtyp / CREATE TYPE PhoneList_vartyp AS VARRAY(10) OF VARCHAR2(20) / CREATE TYPE Address_objtyp AS OBJECT ( Street VARCHAR2(200), City VARCHAR2(200), State CHAR(2), Zip VARCHAR2(20), MEMBER PROCEDURE display ) / CREATE OR REPLACE TYPE Customer_objtyp AS OBJECT ( Custno NUMBER, Custname VARCHAR2(200), Address_obj Address_objtyp, PhoneList_var PhoneList_vartyp, ORDER MEMBER FUNCTION compareCustOrders(x IN Customer_objtyp) RETURN INTEGER, MEMBER PROCEDURE display ) / CREATE TYPE LineItem_objtyp AS OBJECT ( LineItemNo NUMBER, Stock_ref REF StockItem_objtyp, Quantity NUMBER, Discount NUMBER, MEMBER PROCEDURE display ) / CREATE TYPE LineItemList_ntabtyp AS TABLE OF LineItem_objtyp / CREATE TYPE PurchaseOrder_objtyp AS OBJECT ( PONo NUMBER, Cust_ref REF Customer_objtyp, OrderDate DATE, ShipDate DATE, LineItemList_ntab LineItemList_ntabtyp, ShipToAddr_obj Address_objtyp, MAP MEMBER FUNCTION getPONo RETURN NUMBER, MEMBER FUNCTION sumLineItems RETURN NUMBER, MEMBER PROCEDURE purchase_item (item NUMBER, qty NUMBER, discount NUMBER), MEMBER PROCEDURE update_item (lineno NUMBER, item NUMBER, qty NUMBER, discount NUMBER), MEMBER PROCEDURE display ) / CREATE TYPE StockItem_objtyp AS OBJECT ( StockNo NUMBER, Price NUMBER, TaxRate NUMBER ) / -- If no relational data exist, and tables need to be created, then create the -- following object tables CREATE TABLE Customer_objtab OF Customer_objtyp (Custno PRIMARY KEY) OBJECT ID PRIMARY KEY / CREATE TABLE Stock_objtab OF StockItem_objtyp (StockNo PRIMARY KEY) OBJECT ID PRIMARY KEY / CREATE TABLE PurchaseOrder_objtab OF PurchaseOrder_objtyp (PRIMARY KEY (PONo), FOREIGN KEY (Cust_ref) REFERENCES Customer_objtab) OBJECT ID PRIMARY KEY NESTED TABLE LineItemList_ntab STORE AS PoLine_ntab( (PRIMARY KEY(NESTED_TABLE_ID, LineItemNo)) ORGANIZATION INDEX COMPRESS ) RETURN AS LOCATOR / ALTER TABLE PoLine_ntab ADD (SCOPE FOR (Stock_ref) IS stock_objtab); -- Following statement creates an INDEX on the internal column -- "NESTED_TABLE_ID" OF a storage TABLE. CREATE INDEX Po_nidx on PoLine_ntab (NESTED_TABLE_ID) / -- Insertion OF VALUES -- INSERT INTO Stock_objtab VALUES(StockItem_objtyp(1004,6750.00,2)); INSERT INTO Stock_objtab VALUES(StockItem_objtyp(1011,4500.23,2)); INSERT INTO Stock_objtab VALUES(StockItem_objtyp(1534,2234.00,2)); INSERT INTO Stock_objtab VALUES(1535,3456.23,2) / INSERT INTO Customer_objtab VALUES(1,'Jean Nance', Address_objtyp('2 Avocet Drive','Redwood Shores','CA','95054'), PhoneList_vartyp('415-904-0940','408-506-2020')); INSERT INTO Customer_objtab VALUES(2,'John Nike', Address_objtyp('323 College Drive','Edison','NJ','08820'), PhoneList_vartyp('908-904-0940')); INSERT INTO PurchaseOrder_objtab SELECT 1001,REF(C),SYSDATE,'10-MAY-1997',LineItemList_ntabtyp(),NULL FROM Customer_objtab C WHERE C.Custno = 1; INSERT INTO PurchaseOrder_objtab SELECT 2001,REF(C),SYSDATE,'20-MAY-1997', CAST(MULTISET(SELECT 01, REF(S), 12, 0 FROM Stock_objtab S WHERE S.StockNo = 1534) AS LineItemList_ntabtyp), Address_objtyp('55, Madison Ave','Madison','WI','53715') FROM Customer_objtab C WHERE C.Custno = 2; INSERT INTO TABLE(SELECT P.LineItemList_ntab FROM PurchaseOrder_objtab P WHERE P.PONo = 1001) SELECT 01,REF(S),10,10 FROM Stock_objtab S WHERE S.StockNo = 1535; INSERT INTO TABLE(SELECT P.LineItemList_ntab FROM PurchaseOrder_objtab P WHERE P.PONo = 2001) SELECT 10,REF(S), 1,0 FROM Stock_objtab S WHERE S.StockNo = 1004; INSERT INTO TABLE(SELECT P.LineItemList_ntab FROM PurchaseOrder_objtab P WHERE P.PONo = 2001 ) VALUES(LineItem_objtyp( 11,NULL,2,1)) / UPDATE TABLE(SELECT P.LineItemList_ntab FROM PurchaseOrder_objtab P WHERE P.PONo = 2001) plist SET plist.Stock_ref = (SELECT REF(S) FROM Stock_objtab S WHERE S.StockNo = 1011) WHERE plist.LineItemNo = 11 / -- Functional definitions CREATE OR REPLACE TYPE BODY PurchaseOrder_objtyp AS MEMBER FUNCTION sumLineItems RETURN NUMBER IS i INTEGER; StockVal StockItem_objtyp; LineItem LineItem_objtyp; Total NUMBER := 0; BEGIN IF (UTL_COLL.IS_LOCATOR(LineItemList_ntab)) THEN SELECT SUM(L.Quantity * L.Stock_ref.Price) INTO Total FROM TABLE(CAST(LineItemList_ntab AS LineItemList_ntabtyp)) L; ELSE FOR i IN 1..SELF.LineItemList_ntab.COUNT LOOP LineItem := SELF.LineItemList_ntab(i); UTL_REF.SELECT_OBJECT(LineItem.Stock_ref, StockVal); Total := Total + LineItem.Quantity * StockVal.Price * (1 - LineItem.Discount/100); END LOOP; END IF; RETURN Total; END; MAP MEMBER FUNCTION getPONo RETURN NUMBER is BEGIN RETURN PONo; END; MEMBER PROCEDURE purchase_item (item NUMBER, qty NUMBER, discount NUMBER) IS StockRef REF StockItem_objtyp; BEGIN SELECT REF(s) INTO StockRef FROM Stock_objtab s WHERE s.StockNo = item; LineItemList_ntab.EXTEND; LineItemList_ntab(LineItemList_ntab.LAST) := lineitem_objtyp(LineItemList_ntab.LAST, StockRef, qty, discount); END; MEMBER PROCEDURE update_item (lineno NUMBER, item NUMBER, qty NUMBER, discount NUMBER) IS StockRef REF StockItem_objtyp; BEGIN SELECT REF(s) INTO StockRef FROM Stock_objtab s WHERE s.StockNo = item; LineItemList_ntab(lineno).Stock_ref := StockRef; LineItemList_ntab(lineno).Quantity := qty; LineItemList_ntab(lineno).Discount := discount; END; MEMBER PROCEDURE display IS cust Customer_objtyp; BEGIN dbms_output.put_line('Purchase Order ' || pono); dbms_output.put_line(' '); SELECT DEREF(Cust_ref) INTO cust FROM DUAL; cust.display; IF (ShipToAddr_obj IS NOT NULL) THEN dbms_output.put_line('Shipping address:'); ShipToAddr_obj.display; END IF; dbms_output.put_line(' '); dbms_output.put_line('Order date: ' || OrderDate); dbms_output.put_line('Ship date: ' || ShipDate); dbms_output.put_line(' '); dbms_output.put_line('Line Item Quantity Price ' || 'Discount Extension'); FOR i IN 1 .. LineItemList_ntab.COUNT LOOP LineItemList_ntab(i).display; END LOOP; dbms_output.put_line(' '); dbms_output.put_line('Total cost: ' || to_char(sumLineItems, '$999,999,990.99')); END; END; / CREATE OR REPLACE TYPE BODY Customer_objtyp AS ORDER MEMBER FUNCTION compareCustOrders (x IN Customer_objtyp) RETURN INTEGER IS BEGIN RETURN Custno - x.Custno; END; MEMBER PROCEDURE display IS BEGIN dbms_output.put_line(CustName); Address_obj.display; FOR i IN 1 .. PhoneList_var.COUNT LOOP dbms_output.put_line(PhoneList_var(i)); END LOOP; END; END; / CREATE OR REPLACE TYPE BODY Address_objtyp AS MEMBER PROCEDURE display IS BEGIN dbms_output.put_line(Street); dbms_output.put_line(City || ', ' || State || ' ' || Zip); END; END; / CREATE OR REPLACE TYPE BODY LineItem_objtyp AS MEMBER PROCEDURE display IS item StockItem_objtyp; ext NUMBER; textline VARCHAR2(255); BEGIN SELECT DEREF(Stock_Ref) INTO item FROM DUAL; ext := Quantity * item.Price * (1 - Discount/100); textline := to_char(LineItemNo, '999') || ' ' || to_char(item.StockNo, '0999') || ' ' || to_char(Quantity, '9999999') || ' ' || to_char(item.Price, '$99,999.99') || ' ' || to_char(Discount, '90.99') || '% ' || to_char(ext, '$999,999.99'); dbms_output.put_line(textline); END; END; / -- Select the line item list and the Custname FOR each purchase order SELECT DEREF(p.Cust_ref) CUSTOMER_INFO, p.ShipToAddr_obj DESTINATION, p.PONo PURCHASE_ORDER_NUMBER, p.OrderDate ORDER_DATE, CURSOR(SELECT LineItemNo, Quantity, Discount FROM TABLE(p.LineItemList_ntab) li) FROM PurchaseOrder_objtab p WHERE p.PONo = 1001 / -- Select the line item list and the Custname FOR each purchase order. -- Please note this is the same query as above but unnesting feature -- of Oracle8i has been used using TABLE() operator. SELECT DEREF(p.Cust_ref) CUSTOMER_INFO, p.ShipToAddr_obj DESTINATION, p.PONo PURCHASE_ORDER_NUMBER, p.OrderDate ORDER_DATE, li.LineItemNo, li.Quantity, li.Discount FROM PurchaseOrder_objtab p, TABLE(p.LineItemList_ntab) li WHERE p.PONo = 1001 / -- Select the Total value FOR each purchse_order SELECT p.PONo PURCHASE_ORDER_NUMBER, p.sumLineItems() SUM_LINE_ITEMS FROM PurchaseOrder_objtab p / -- Select the line items and the purchase numbers FOR all those poUs having -- a StockNo 1535 SELECT po.PONo PURCHASE_ORDER_NUMBER, po.Cust_ref.Custno CUSTOMER_NUMBER, li.LineItemNo LINE_ITEM_NO, li.Stock_ref.StockNo STOCK_NO, li.Quantity QUANTITY, li.Discount DISCOUNT FROM PurchaseOrder_objtab po, TABLE(po.LineItemList_ntab) li WHERE li.Stock_ref.StockNo = 1535 / -- Example of how Varray column can be unnested/flattened in -- Oracle8i using TABLE() operator. SELECT p1.custno, p2.* FROM Customer_objtab p1, TABLE( p1.PhoneList_var)p2 / -- USING PL/SQL TO CALL TYPE METHODS -- -- Required for DBMS_OUTPUT SET SERVEROUTPUT ON FORMAT WRAPPED -- Display all customer info DECLARE cref REF Customer_objtyp; cust Customer_objtyp; CURSOR cr IS SELECT REF(c) FROM Customer_objtab c; BEGIN OPEN cr; LOOP FETCH cr INTO cref; EXIT WHEN cr%NOTFOUND; UTL_REF.SELECT_OBJECT(cref, cust); cust.display; dbms_output.put_line(' '); END LOOP; CLOSE cr; END; / -- Display purchase order CREATE OR REPLACE PROCEDURE display_order (ponum NUMBER) IS poref REF PurchaseOrder_objtyp; po PurchaseOrder_objtyp; BEGIN SELECT REF(p) INTO poref FROM PurchaseOrder_objtab p WHERE p.pono = ponum; UTL_REF.SELECT_OBJECT(poref, po); po.display; END; / BEGIN display_order(1001); END; / -- Add to purchase order -- This procedure uses the LOCK_OBJECT and UPDATE_OBJECT procedures in -- package UTL_REF to modify the nested table of line items CREATE OR REPLACE PROCEDURE add_item (ponum NUMBER, stockno NUMBER, qty NUMBER, discount NUMBER) IS poref REF PurchaseOrder_objtyp; po PurchaseOrder_objtyp; BEGIN SELECT REF(p) INTO poref FROM PurchaseOrder_objtab p WHERE p.pono = ponum; UTL_REF.LOCK_OBJECT(poref, po); po.purchase_item(stockno, qty, discount); UTL_REF.UPDATE_OBJECT(poref, po); END; / BEGIN add_item(1001, 1534, 6, 20); display_order(1001); END; / -- Change a line item -- This procedure updates the line items list using SQL instead of UTL_REF. CREATE OR REPLACE PROCEDURE change_item (ponum NUMBER, lineno NUMBER, stockno NUMBER, qty NUMBER, discount NUMBER) IS poref REF PurchaseOrder_objtyp; po PurchaseOrder_objtyp; BEGIN SELECT REF(p) INTO poref FROM PurchaseOrder_objtab p WHERE p.pono = ponum FOR UPDATE OF p.LineItemList_ntab; UTL_REF.SELECT_OBJECT(poref, po); po.update_item(lineno, stockno, qty, discount); UPDATE PurchaseOrder_objtab p SET p.LineItemList_ntab = po.LineItemList_ntab WHERE p.pono = ponum; END; / BEGIN change_item(1001, 1, 1011, 7, 35); display_order(1001); END; / -- Object Views -- If relational schema exists WITH relational tables containing the -- purchase order, lineitem and customer data, then objects may be -- materialized from the relational data WITH the help of object views. CREATE OR REPLACE VIEW Customer_objview OF Customer_objtyp WITH OBJECT OID(Custno) AS SELECT C.Custno, C.Custname, Address_objtyp(C.Street,C.City,C.State,C.Zip), PhoneList_vartyp(Phone1,Phone2,Phone3) FROM Customer_reltab C / CREATE OR REPLACE VIEW Stock_objview OF StockItem_objtyp WITH OBJECT OID(StockNo) AS SELECT * FROM Stock_reltab / CREATE OR REPLACE VIEW PurchaseOrder_objview OF PurchaseOrder_objtyp WITH OBJECT OID (PONo) AS SELECT P.PONo, MAKE_REF(Customer_objview,P.Custno), P.OrderDate, P.ShipDate, CAST( MULTISET(SELECT LineItem_objtyp(L.LineItemNo, MAKE_REF(Stock_objview,L.StockNo), L.Quantity, L.Discount) FROM LineItems_reltab L WHERE L.PONo= P.PONo) AS LineItemList_ntabtyp), Address_objtyp(P.ToStreet,P.ToCity,P.ToState,P.ToZip) FROM PurchaseOrder_reltab P / ------- -- Since OBJECT views queries are complex making them inherently non-updatable, -- Instead-OF triggers may be specified FOR them to make them updatable. -- For example, the following creates an INSTEAD-OF TRIGGER on the -- PurchaseOrder_tab VIEW -- which encapsulates the semantics of inserting into that view. CREATE OR REPLACE TRIGGER POView_instdinserttr INSTEAD OF INSERT on PurchaseOrder_objview DECLARE LineItems_ntab LineItemList_ntabtyp; i INTEGER; CustVar_obj Customer_objtyp; StockVar_obj StockItem_objtyp; StockVarTemp_ref REF StockItem_objtyp; BEGIN LineItems_ntab := :new.LineItemList_ntab; UTL_REF.SELECT_OBJECT(:new.Cust_ref, CustVar_obj); INSERT INTO PurchaseOrder_reltab VALUES(:new.PONo,CustVar_obj.Custno,:new.OrderDate,:new.ShipDate, :new.ShipToAddr_obj.Street,:new.ShipToAddr_obj.City, :new.ShipToAddr_obj.State,:new.ShipToAddr_obj.Zip) ; FOR i in 1..LineItems_ntab.count LOOP UTL_REF.SELECT_OBJECT(LineItems_ntab(i).Stock_ref, StockVar_obj); INSERT INTO LineItems_reltab VALUES(LineItems_ntab(i).LineItemNo,:new.PONo,StockVar_obj.StockNo, LineItems_ntab(i).Quantity,LineItems_ntab(i).Discount); END LOOP; END; / CREATE OR REPLACE TRIGGER POLineItems_instdinsertr INSTEAD OF INSERT ON NESTED TABLE LineItemList_ntab OF PurchaseOrder_objview DECLARE StockVar StockItem_objtyp; BEGIN UTL_REF.SELECT_OBJECT(:NEW.Stock_ref, StockVar); INSERT INTO LineItems_reltab VALUES (:NEW.LineItemNo, :PARENT.PONo, StockVar.StockNo, :NEW.Quantity, :NEW.Discount); END; / CREATE OR REPLACE TRIGGER POLineItems_instddeltr INSTEAD OF DELETE ON NESTED TABLE LineItemList_ntab OF PurchaseOrder_objview BEGIN DELETE FROM LineItems_reltab WHERE LineItemNo = :OLD.LineItemNo AND PONo = :PARENT.PONo; END; / CREATE OR REPLACE TRIGGER CustView_instdinserttr INSTEAD OF INSERT on Customer_objview DECLARE Phones_var PhoneList_vartyp; TPhone1 Customer_reltab.Phone1%TYPE := NULL; TPhone2 Customer_reltab.Phone2%TYPE := NULL; TPhone3 Customer_reltab.Phone3%TYPE := NULL; BEGIN Phones_var := :new.PhoneList_var; IF Phones_var.COUNT > 2 then TPhone3 := Phones_var(3); END IF; IF Phones_var.COUNT > 1 then TPhone2 := Phones_var(2); END IF; IF Phones_var.COUNT > 0 then TPhone1 := Phones_var(1); END IF; INSERT INTO Customer_reltab VALUES(:new.Custno,:new.Custname,:new.Address_obj.Street, :new.Address_obj.City,:new.Address_obj.State, :new.Address_obj.Zip, TPhone1,TPhone2,TPhone3); END; / CREATE OR REPLACE TRIGGER StockView_instdinsertr INSTEAD OF INSERT on Stock_objview BEGIN INSERT INTO Stock_reltab VALUES(:new.StockNo,:new.Price,:new.TaxRate); END; / INSERT INTO Customer_objview VALUES (13,'Ellan White', Address_objtyp('25, I Street','memphis','TN','05456'), PhoneList_vartyp('901-000-0000')); COMMIT / INSERT INTO PurchaseOrder_objview SELECT 3001, REF(c),SYSDATE,SYSDATE, CAST(MULTISET(SELECT LineItem_objtyp(41, REF(S),20,1) FROM Stock_objview S WHERE S.StockNo = 1535) AS LineItemList_ntabtyp), Address_objtyp('22 Nothingame Ave','Cockstown','AZ','44045') FROM Customer_objview c WHERE c.Custno = 1 / DELETE FROM TABLE(SELECT p.LineItemList_ntab FROM PurchaseOrder_objview p WHERE p.PONo = 3001) L WHERE L.LineItemNo = 41 / INSERT INTO TABLE(SELECT p.LineItemList_ntab FROM PurchaseOrder_objview p WHERE p.PONo = 3001) SELECT LineItem_objtyp(41, REF(S),20,1) FROM Stock_objview S WHERE S.StockNo = 1535 / SELECT DEREF(p.Cust_ref) CUSTOMER_INFO, p.ShipToAddr_obj DESTINATION, p.PONo PURCHASE_ORDER_NUMBER, p.OrderDate ORDER_DATE, CURSOR(SELECT LineItemNo, Quantity, Discount FROM TABLE(p.LineItemList_ntab) li) FROM PurchaseOrder_objview p WHERE p.PONo = 1001 / -- Please note this is the same query as above but unnesting feature -- of Oracle8i has been used using TABLE() operator. SELECT DEREF(p.Cust_ref) CUSTOMER_INFO, p.ShipToAddr_obj DESTINATION, p.PONo PURCHASE_ORDER_NUMBER, p.OrderDate ORDER_DATE, li.LineItemNo, li.Quantity, li.Discount FROM PurchaseOrder_objview p, TABLE(p.LineItemList_ntab) li WHERE p.PONo = 1001 / -- Select the TotalSELF value FOR each purchse_order SELECT p.PONo,p.sumLineItems () FROM PurchaseOrder_objview p / -- SELECT the lineitems and the purchase order numbers -- returning the linitems as a nested cursor SELECT po.PONo PURCHASE_ORDER_NUMBER, po.Cust_ref.Custno CUSTOMER_NUMBER, CURSOR(SELECT * FROM TABLE(po.LineItemList_ntab) li WHERE li.Stock_ref.StockNo = 1535) FROM PurchaseOrder_objview po / -- Please note this is the same query as above but unnesting feature -- of Oracle8i has been used using TABLE() operator. SELECT po.PONo PURCHASE_ORDER_NUMBER, po.Cust_ref.Custno CUSTOMER_NUMBER, li.* FROM PurchaseOrder_objview po, TABLE(po.LineItemList_ntab) li WHERE li.Stock_ref.StockNo = 1535; -- Select the line items and the purchase numbers FOR all those poUs having -- a StockNo 1535 SELECT po.PONo PURCHASE_ORDER_NUMBER, po.Cust_ref.Custno CUSTOMER_NUMBER, li.LineItemNo LINEITEM_NUMBER, li.Quantity QUANTITY FROM PurchaseOrder_objview po, TABLE(po.LineItemList_ntab) li WHERE li.Stock_ref.StockNo = 1535 / -- Select the Total value FOR each purchse_order SELECT p.PONo PURCHASE_ORDER_NUMBER, p.sumLineItems() SUM_LINE_ITEMS FROM PurchaseOrder_objtab p / COMMIT / CONNECT system/manager DROP USER po CASCADE / /* demonstrate creating object views using MAKE_REF and also self-referencing view */ CONNECT system/manager DROP USER fnd CASCADE; GRANT CONNECT, RESOURCE TO fnd IDENTIFIED BY fnd; CONNECT fnd/fnd CREATE TABLE fnd_application ( application_id NUMBER PRIMARY KEY, application_short_name VARCHAR2(50) NOT NULL, application_name VARCHAR2(240) ); CREATE TABLE fnd_form_functions( function_id NUMBER PRIMARY KEY, function_name VARCHAR2(30) NOT NULL, application_id NUMBER, form_id NUMBER, parameters VARCHAR2(2000) ); CREATE TABLE fnd_menus ( menu_id NUMBER PRIMARY KEY, menu_name VARCHAR2(30) NOT NULL ); CREATE TABLE fnd_form_vl ( application_id NUMBER PRIMARY KEY, form_id NUMBER NOT NULL, form_name VARCHAR2(30) NOT NULL, AUDIT_ENABLED_FLAG VARCHAR2(1) NOT NULL, user_form_name VARCHAR2(80) NOT NULL, description VARCHAR2(240) ); CREATE TABLE fnd_form_functions_vl ( function_id NUMBER PRIMARY KEY, function_name VARCHAR2(30) NOT NULL, application_id NUMBER, form_id NUMBER, parameters VARCHAR2(2000), type VARCHAR2(30), user_function_name VARCHAR2(80) NOT NULL, description VARCHAR2(240) ); CREATE TABLE fnd_menu_entries_vl ( menu_id NUMBER PRIMARY KEY, entry_sequence NUMBER NOT NULL, sub_menu_id NUMBER, function_id NUMBER, prompt VARCHAR2(30), description VARCHAR2(240) ); CREATE TABLE fnd_menus_vl ( menu_id NUMBER PRIMARY KEY, menu_name VARCHAR2(30) NOT NULL, user_menu_name VARCHAR2(80) NOT NULL, description VARCHAR2(240) ); CREATE TYPE fnd_application_t AS OBJECT ( application_short_name varchar2(50), application_name varchar2(240) ) / CREATE OR REPLACE VIEW fnd_application_object_view OF fnd_application_t WITH OBJECT OID(application_short_name) AS SELECT application_short_name, application_name FROM fnd_application; CREATE TYPE fnd_form_t AS OBJECT ( form_name VARCHAR2(30), application REF fnd_application_t, user_form_name varchar2(80), description varchar2(240) ) / CREATE OR REPLACE VIEW fnd_form_view OF fnd_form_t WITH OBJECT OID(form_name) AS SELECT F.form_name, MAKE_REF(fnd_application_object_view, A.application_short_name), F.user_form_name, F.description FROM fnd_form_vl F, fnd_application A WHERE F.application_id = A.application_id; CREATE TYPE fnd_function_t AS OBJECT ( function_name varchar2(30), form REF fnd_form_t, type varchar2(30), parameters varchar2(2000), user_function_name varchar2(80), description varchar2(240) ) / CREATE OR REPLACE VIEW fnd_function_object_view OF fnd_function_t WITH OBJECT OID(function_name) AS SELECT N.function_name, MAKE_REF(fnd_form_view, F.form_name), N.type, N.parameters, N.user_function_name, N.description FROM fnd_form_functions_vl N, fnd_form_vl F WHERE N.form_id = F.form_id; CREATE TYPE fnd_menu_t / CREATE TYPE fnd_menu_entry_t AS OBJECT ( entry_sequence number, prompt varchar2(30), description varchar2(240), submenu REF fnd_menu_t, function REF fnd_function_t ) / CREATE TYPE fnd_menu_entry_list_t AS TABLE OF fnd_menu_entry_t / CREATE TYPE fnd_menu_t AS OBJECT ( menu_name varchar2(30), user_menu_name varchar2(80), description varchar2(240), entries fnd_menu_entry_list_t ) / /* create self-reference view */ CREATE OR REPLACE FORCE VIEW fnd_menu_object_view OF fnd_menu_t WITH OBJECT OID(menu_name) AS SELECT M.menu_name, M.user_menu_name, M.description, CAST( MULTISET( SELECT fnd_menu_entry_t( Q.entry_sequence, Q.prompt, Q.description, MAKE_REF(fnd_menu_object_view, S.menu_name), NULL) FROM fnd_menu_entries_vl Q, fnd_menus S WHERE Q.menu_id = M.menu_id AND Q.sub_menu_id = S.menu_id ) AS fnd_menu_entry_list_t) FROM fnd_menus_vl M; CONNECT SYSTEM/MANAGER DROP USER fnd CASCADE / SET ECHO OFF