Object Views and Nested Tables
Use object views to present relational data as an object-relational model.
oracle miscconfigurationintermediate
by OracleDba
14 views
Use object views to present relational data as an object-relational model.
1234567891011121314151617181920212223242526272829303132333435363738
CREATE TABLE masters (
id NUMBER(10) NOT NULL,
name VARCHAR2(50) NOT NULL
)
/
ALTER TABLE masters ADD (
CONSTRAINT masters_pk PRIMARY KEY (id)
)
/
CREATE SEQUENCE masters_seq;
CREATE TABLE details (
id NUMBER(10) NOT NULL,
master_id NUMBER(10) NOT NULL,
name VARCHAR2(50) NOT NULL
)
/
ALTER TABLE details ADD (
CONSTRAINT details_pk PRIMARY KEY (id)
)
/
ALTER TABLE details ADD (
CONSTRAINT details_masters_fk
FOREIGN KEY (master_id)
REFERENCES masters (id)
)
/
CREATE INDEX details_masters_fk_i
ON details(master_id)
/
CREATE SEQUENCE details_seq;123456789
CREATE OR REPLACE TYPE t_details_row AS OBJECT (
id NUMBER(10),
master_id NUMBER(10),
name VARCHAR2(50)
);
/
CREATE OR REPLACE TYPE t_details_tab AS TABLE OF t_details_row;
/1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
CREATE OR REPLACE VIEW masters_v AS
SELECT m.id,
m.name,
CAST (MULTISET (SELECT d.id,
d.master_id,
d.name
FROM details d
WHERE d.master_id = m.id) AS t_details_tab) details
FROM masters m
/
CREATE OR REPLACE TRIGGER masters_v_trg
INSTEAD OF INSERT ON masters_v
FOR EACH ROW
BEGIN
-- Insert the master record.
INSERT INTO masters (id, name)
VALUES (:new.id, :new.name);
-- Loop through the details collection, inserting each record into the base table.
FOR i IN :new.details.first .. :new.details.last LOOP
INSERT INTO details (id, master_id, name)
VALUES (:new.details(i).id, :new.details(i).master_id, :new.details(i).name);
END LOOP;
END;
/
DECLARE
l_master_id NUMBER(10);
l_details_tab t_details_tab := t_details_tab();
FUNCTION get_next_detail_id RETURN NUMBER AS
l_detail_id details.id%TYPE;
BEGIN
SELECT details_seq.NEXTVAL
INTO l_detail_id
FROM dual;
RETURN l_detail_id;
END get_next_detail_id;
BEGIN
-- Get the id of the master record.
SELECT masters_seq.NEXTVAL
INTO l_master_id
FROM dual;
-- Populate the details collection prior to insert.
l_details_tab.extend;
l_details_tab(l_details_tab.last) := t_details_row(get_next_detail_id, l_master_id, 'Test Child Insert 1');
l_details_tab.extend;
l_details_tab(l_details_tab.last) := t_details_row(get_next_detail_id, l_master_id, 'Test Child Insert 2');
-- Insert the data via the object view.
INSERT INTO masters_v
(id, name, details)
VALUES
(l_master_id, 'Test Master Insert', l_details_tab);
COMMIT;
END;
/
SQL> SELECT * FROM masters;
ID NAME
---------- --------------------------------------------------
1 Test Master Insert
1 row selected.
SQL> SELECT * FROM details;
ID MASTER_ID NAME
---------- ---------- --------------------------------------------------
1 1 Test Child Insert 1
2 1 Test Child Insert 2
2 rows selected.
SQL> SELECT * FROM masters_v;
ID NAME
---------- --------------------------------------------------
DETAILS(ID, MASTER_ID, NAME)
----------------------------------------------------------------------------------------------------
1 Test Master Insert
T_DETAILS_TAB(T_DETAILS_ROW(1, 1, 'Test Child Insert 1'), T_DETAILS_ROW(2, 1, 'Test Child Insert 2')
)
1 row selected.
SQL>1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
CREATE TABLE masters_2 (
id NUMBER(10) NOT NULL,
name VARCHAR2(50) NOT NULL,
details t_details_tab
)
NESTED TABLE details STORE AS details_2
/
DECLARE
l_master_id NUMBER(10);
l_details_tab t_details_tab := t_details_tab();
FUNCTION get_next_detail_id RETURN NUMBER AS
l_detail_id NUMBER;
BEGIN
SELECT details_seq.NEXTVAL
INTO l_detail_id
FROM dual;
RETURN l_detail_id;
END get_next_detail_id;
BEGIN
-- Get the id of the master record.
SELECT masters_seq.NEXTVAL
INTO l_master_id
FROM dual;
-- Populate the details collection prior to insert.
l_details_tab.extend;
l_details_tab(l_details_tab.last) := t_details_row(get_next_detail_id, l_master_id, 'Test Child Insert 1');
l_details_tab.extend;
l_details_tab(l_details_tab.last) := t_details_row(get_next_detail_id, l_master_id, 'Test Child Insert 2');
-- Insert the data via the object view.
INSERT INTO masters_2
(id, name, details)
VALUES
(l_master_id, 'Test Master Insert', l_details_tab);
COMMIT;
END;
/
SQL> SELECT * FROM masters_2;
ID NAME
---------- --------------------------------------------------
DETAILS(ID, MASTER_ID, NAME)
----------------------------------------------------------------------------------------------------
2 Test Master Insert
T_DETAILS_TAB(T_DETAILS_ROW(3, 2, 'Test Child Insert 1'), T_DETAILS_ROW(4, 2, 'Test Child Insert 2')
)
1 row selected.
SQL>123456789
DROP VIEW masters_v;
DROP TABLE details;
DROP TABLE masters;
DROP TABLE masters_2;
DROP SEQUENCE details_seq;
DROP SEQUENCE masters_seq;
DROP TYPE t_details_tab;
DROP TYPE t_details_row;
PURGE RECYCLEBIN;Please to add comments
No comments yet. Be the first to comment!