简体   繁体   中英

3 level nesting tables in SQL

I wanted to create following 3 - level structure using Oracle object programming aspects:
- Bosses
- - Managers
- - - Employees

When I want to run script for creating table tab_univ_bosses following exception occurs in last line:

Error at Command Line:31 Column:3
Error report:
SQL Error: ORA-22913: "must specify table name for nested table column or attribute"
*Cause:    The storage clause is not specified for a nested table column
           or attribute.
*Action:   Specify the nested table storage clause for the nested table
           column or attribute.

Error starting at line 33 in command:
NESTED TABLE managers STORE AS tab_univ_managers
Error report:
Unknown Command

This is my code:

-- TYPE <EMPLOYEE>
create or replace 
TYPE type_Employee AS OBJECT (
  name                VARCHAR2(30), 
  department_name     VARCHAR2(30),
  second_name         VARCHAR2(30),
  manager             REF type_Employee 
);

CREATE or replace TYPE type_ListEmployees 
AS TABLE OF type_Employee;

-- TYPE <MANAGER>
create or replace 
TYPE type_Manager AS OBJECT (
  userData type_Employee,
  manager REF type_Employee, 
  listEmployees type_ListEmployees
);
NESTED TABLE listEmployees STORE AS tab_univ_employees 

CREATE or replace TYPE type_ListManagers 
AS TABLE OF type_ListEmployees;

-- BASE TABLE
CREATE TABLE tab_univ_bosses (
  id        NUMBER PRIMARY KEY,
  userData  type_Employee,
  managers  type_ListManagers
);
NESTED TABLE managers STORE AS tab_univ_managers <--- There is a problem...

You can do this using a single table:

create or replace 
TYPE type_Employee AS OBJECT (
  name                VARCHAR2(30), 
  department_name     VARCHAR2(30),
  second_name         VARCHAR2(30),
  manager             REF type_Employee 
);
/

CREATE TABLE Employees OF type_Employee (
  manager SCOPE IS Employees
)
/

INSERT INTO Employees VALUES ( 'Big', 'Admin', 'Boss', NULL );
INSERT INTO Employees VALUES ( 'Middle', 'Accounts', 'Manager',    ( SELECT REF(e) FROM Employees e WHERE name = 'Big' AND second_name = 'Boss' ) );
INSERT INTO Employees VALUES ( 'Other', 'Sales', 'Manager',        ( SELECT REF(e) FROM Employees e WHERE name = 'Big' AND second_name = 'Boss' ) );
INSERT INTO Employees VALUES ( 'Junior', 'Accounts', 'Accountant', ( SELECT REF(e) FROM Employees e WHERE name = 'Middle' AND second_name = 'Manager' ) );
INSERT INTO Employees VALUES ( 'Junior', 'Sales', 'Salesman',      ( SELECT REF(e) FROM Employees e WHERE name = 'Other' AND second_name = 'Manager' ) );

-- Get everyone in hierarchical order.
SELECT name, second_name, department_name, LEVEL
FROM   Employees e
START WITH manager IS NULL
CONNECT BY PRIOR name = DEREF( e.MANAGER ).name
AND PRIOR second_name = DEREF( e.MANAGER ).second_name
ORDER SIBLINGS BY name, second_name;

-- Get the employees which have the manager: 'Middle', 'Manager'
SELECT name, second_name, department_name
FROM  Employees e
WHERE DEREF( e.Manager ).Name = 'Middle'
AND DEREF( e.Manager ).Second_Name = 'Manager';

However if you really want to use that structure then:

create or replace 
TYPE type_Employee AS OBJECT (
  name                VARCHAR2(30), 
  department_name     VARCHAR2(30),
  second_name         VARCHAR2(30),
  manager             REF type_Employee 
);
/

CREATE or replace TYPE type_ListEmployees 
AS TABLE OF type_Employee;
/

create or replace 
TYPE type_Manager AS OBJECT (
  userData type_Employee,
  manager REF type_Employee, 
  listEmployees type_ListEmployees
);
/

CREATE or replace TYPE type_ListManagers 
AS TABLE OF type_Manager;
/

CREATE TABLE tab_univ_bosses (
  id        NUMBER PRIMARY KEY,
  userData  type_Employee,
  managers  type_ListManagers
)
NESTED TABLE managers STORE AS tab_univ_managers (
  NESTED TABLE listEmployees STORE AS tab_univ_employees
);
/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM