3 level nesting tables in SQL - 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
);
/

Related

oracle trigger pl sql

I have a database user that contains four tables department, employee, address and contact info, then stored 5 Records in each table, and wrote the PL/SQL Statement for the following:
Stored a record into employee, address and contact using trigger.
the insert into view is not working ! it results in error ? can you guys help me with this ?
this is my code :
-- Create Tables :
CREATE TABLE address (
code int primary key,
city varchar2(30),
street varchar2(30)
);
create table Department (
DepId int primary key ,
Dep_Name varchar2(30) ,
Dep_adress varchar(30));
create table Employee (
Emp_Id int primary key ,
firstName varchar2(30),
lastName varchar2(30),
salary int,
Dep_Id int references Department (DepId),
Code int references address (code));
CREATE TABLE contact_info (
email varchar2(30) primary key ,
phone int ,
EmpId int references Employee (Emp_Id));
-- insert :
insert into Department values (1,'IT','Amman');
insert into Department values (2,'CS','Jerash');
insert into Department values (3,'accounting','Amman');
insert into Department values (4,'managment','Amman');
insert into Department values (5,'employment','Amman');
insert into address values (50,'Amman','AAA');
insert into address values (60,'Amman','AAB');
insert into address values (70,'Amman','AAC');
insert into address values (80,'Jerash','AAD');
insert into address values (90,'Irbid','AAE');
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (1,'john' , 'samo' , 1000 , (select DepId from Department where Dep_Name = 'IT'),(select code from address where street = 'AAA'));
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (2,'mark' , 'wol' , 2000 , (select DepId from Department where Dep_Name = 'IT'),(select code from address where street = 'AAB'));
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (3,'ahmad' , 'moh' , 1100 , (select DepId from Department where Dep_Name = 'IT'),(select code from address where street = 'AAC'));
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (4,'maher' , 'imk' , 1700 , (select DepId from Department where Dep_Name = 'CS'),(select code from address where street = 'AAD'));
insert into Employee (Emp_Id,firstName,lastName,salary,Dep_Id,Code) values (5,'ali' , 'geh' , 1200 , (select DepId from Department where Dep_Name = 'CS'),(select code from address where street = 'AAE'));
insert into contact_info values ('john#gmail.com',0785602200, (select Emp_Id from Employee where salary = 1000));
insert into contact_info values ('mark#gmail.com',0785602201, (select Emp_Id from Employee where salary = 2000));
insert into contact_info values ('ahmad#gmail.com',0785602202, (select Emp_Id from Employee where salary = 1100));
insert into contact_info values ('maher#gmail.com',0785602203, (select Emp_Id from Employee where salary = 1700));
insert into contact_info values ('ali#gmail.com',0785602204, (select Emp_Id from Employee where salary = 1200));
-- trigger :
CREATE VIEW vw_address1 AS
SELECT
code,
city,
street
FROM
address;
CREATE OR REPLACE TRIGGER new_trg2
INSTEAD OF INSERT ON vw_address1
FOR EACH ROW
DECLARE
l_code NUMBER;
BEGIN
-- insert a new address first
INSERT INTO address(code,city, street)
VALUES(:NEW.code,:NEW.city, :NEW.street)
RETURNING code INTO l_code;
END;
insert into vw_address1(code,city,street) values (2,'Amman','AAB');

Oracle Database - REF unsupported data type

So I have three tables, Staff, Book, and Sale.
For Staff:
CREATE TYPE StaffType AS OBJECT (
ID VARCHAR2(5),
Name VARCHAR2(30)
);
/
CREATE TABLE Staff of StaffType;
For Book:
CREATE TYPE BookType AS OBJECT (
B_ID VARCHAR2(8));
/
CREATE TABLE Book of TicketType;
For Sale:
CREATE TYPE SaleType AS OBJECT (
S_ID VARCHAR2(8),
S_Date VARCHAR2(10),
Price NUMBER(10),
With REF StaffType,
For REF BookType );
/
CREATE TABLE Sale of SaleType (
Scope for (With) is Staff,
Scope for (For) is Book);
So I inserted a row in Sale table like this
insert into Sale VALUES(SaleType('S12','33th',22,(SELECT REF(c) FROM Staff c WHERE c.ID='C13'),(SELECT REF(t) FROM Book t WHERE t.B_ID='T18'));
however, I get the following error:
ORA-00917: missing comma
I don't understand why I am getting this error.. What comma did I miss?
EDIT: I followed the solution of #thatjeffsmith and although the insert statement works, when I try to view my table, I get the following error:
ORA-00932: inconsistent datatypes: expected CHAR got REF SQL_VTJOLYEBVKAOJEHORTCXVPTBP.STAFFTYPE
here is the code.. I removed HR. before Book and Staff from sale table declaration because that was causing the worksheet to show an error stating that Staff and Book are out of scope. Here is the code:
CREATE TYPE STAFFTYPE AS OBJECT (
ID VARCHAR2(5),
NAME VARCHAR2(30)
);
/
CREATE TABLE STAFF OF STAFFTYPE;
/
INSERT INTO STAFF VALUES('C13','James');
/
CREATE TYPE BOOKTYPE AS OBJECT (
B_ID VARCHAR2(8)
);
/
CREATE TABLE BOOK OF BOOKTYPE;
/
INSERT INTO BOOK VALUES('T18');
/
CREATE TYPE SALETYPE AS OBJECT (
S_ID VARCHAR2(8),
S_DATE VARCHAR2(10),
PRICE NUMBER(10),
WITHS REF STAFFTYPE,
FORS REF BOOKTYPE
);
/
CREATE TABLE SALE OF SALETYPE (
SCOPE FOR ( WITHS ) IS STAFF,
SCOPE FOR ( FORS ) IS BOOK
);
INSERT INTO SALE VALUES ( SALETYPE(
'S12', '33th',
22,
(
SELECT REF(C)
FROM STAFF C
WHERE C.ID = 'C13'
),
(
SELECT REF(T)
FROM BOOK T
WHERE T.B_ID = 'T18'
)
) );
SELECT * FROM SALE;
WITH and FOR are keywords, not available as a table or column name. You could "QUOTE" these, but DO NOT DO THAT - it will make your life much harder going forward.
Your BOOK table is wrong, you're using a TYPE that doesn't exist per your example.
And your INSERT is missing the last ')'
CREATE TYPE STAFFTYPE AS OBJECT (
ID VARCHAR2(5),
NAME VARCHAR2(30)
);
/
CREATE TABLE STAFF OF STAFFTYPE;
CREATE TYPE BOOKTYPE AS OBJECT (
B_ID VARCHAR2(8)
);
/
CREATE TABLE BOOK OF BOOKTYPE;
CREATE TYPE SALETYPE AS OBJECT (
S_ID VARCHAR2(8),
S_DATE VARCHAR2(10),
PRICE NUMBER(10),
WITHS REF STAFFTYPE,
FORS REF BOOKTYPE
);
/
CREATE TABLE SALE OF SALETYPE (
SCOPE FOR ( WITHS ) IS HR.STAFF,
SCOPE FOR ( FORS ) IS HR.BOOK
);
INSERT INTO SALE VALUES ( SALETYPE(
'S12', '33th',
22,
(
SELECT REF(C)
FROM STAFF C
WHERE C.ID = 'C13'
),
(
SELECT REF(T)
FROM BOOK T
WHERE T.B_ID = 'T18'
)
) );

Why is the table view not coming?

I am new to Oracle. The Oracle live SQL shorthand gave ready-made code on the departments and employees model.
I don't understand why the code is not viewing any table although I wrote a select statement. I don't understand the execution protocol.
link
create table departments (
name varchar2(255) not null,
location varchar2(4000),
country varchar2(4000)
)
;
create table employees (
department_id number
constraint employees_department_id_fk
references departments on delete cascade,
name varchar2(50) not null,
email varchar2(255),
cost_center number,
date_hired date,
job varchar2(255)
)
;
insert into departments (
name,
location,
country
) values (
'Security',
'Tanquecitos',
'United States'
);
insert into departments (
name,
location,
country
) values (
'Travel',
'Sugarloaf',
'United States'
);
insert into departments (
name,
location,
country
) values (
'Office of the CEO',
'Dale City',
'United States'
);
insert into departments (
name,
location,
country
) values (
'Security',
'Grosvenor',
'United States'
);
commit;
-- load data
insert into employees (
department_id,
name,
email,
cost_center,
date_hired,
job
) values (
1,
'Gricelda Luebbers',
'gricelda.luebbers#aaab.com',
20,
sysdate - 94,
'Systems Designer'
);
insert into employees (
department_id,
name,
email,
cost_center,
date_hired,
job
) values (
1,
'Dean Bollich',
'dean.bollich#aaac.com',
11,
sysdate - 74,
'Legal Assistant'
);
insert into employees (
department_id,
name,
email,
cost_center,
date_hired,
job
) values (
1,
'Milo Manoni',
'milo.manoni#aaad.com',
21,
sysdate - 68,
'Systems Designer'
);
insert into employees (
department_id,
name,
email,
cost_center,
date_hired,
job
) values (
1,
'Laurice Karl',
'laurice.karl#aaae.com',
78,
sysdate - 73,
'Programmer'
);
select
departments.name department_name,
departments.location location,
departments.country country,
employees.name employee_name,
employees.email email,
employees.cost_center cost_center,
employees.date_hired date_hired,
employees.job job
from
departments,
employees;
This is the output they are showing after running:
Table created.
ORA-02268: referenced table does not have a primary key
1 row(s) inserted.
1 row(s) inserted.
1 row(s) inserted.
1 row(s) inserted.
Statement processed.
ORA-00942: table or view does not exist
ORA-00942: table or view does not exist
ORA-00942: table or view does not exist
ORA-00942: table or view does not exist
ORA-00942: table or view does not exist
Your table departments does not have a primary key, so the constraint in table employees produces an error, and the table employees is not created.
You should refactor your SQL code, adding a proper primary key to the table involved and manage the insert value properly:
create table departments (
id numeric(10) not null
name varchar2(255) not null,
location varchar2(4000),
country varchar2(4000),
CONSTRAINT id PRIMARY KEY (id)
)
;

REF querying with object-relational database

So currently my database stands as follows:
//branch table
create type branch_Type as object(bID number(6), branch_id ref branch_Type, b_street varchar2(20), b_city varchar2(20), b_p_code varchar2(8), b_bPhone number(14));
create table branch of branch_Type;
INSERT INTO branch VALUES(branch_Type('901', NULL, 'Market', 'Edinburgh', 'EH5 1AB', '01311235560'));
INSERT INTO branch VALUES(branch_Type('908', NULL, 'Bridge', 'Glasgow', 'G18 1QQ', '01413214556'));
insert into branch SELECT branch_Type('901', ref(e), b_street, b_city, b_p_code, b_bPhone) from branch e where e.BID = '901';
insert into branch SELECT branch_Type('908', ref(e), b_street, b_city, b_p_code, b_bPhone) from branch e where e.BID = '908';
//employee table
create type employee_Type as object(e_bid ref branch_Type, empID number(8), e_street varchar2(20), e_city varchar2(20), e_p_code varchar2(8), e_title varchar2(4), e_firstname_surname varchar2(20), emphomephone number(14), emp_mobile_1_2 number(22), supervisorID number(6), e_position varchar2(20), salary number(5), e_ninum varchar2(8), joindate date);
create table employee of employee_Type;
insert into employee select ref(e), '101', 'Dart', 'Edinburgh', 'EH1 05T', 'Mrs', 'Alison Smith', '01312125555', '0770562344307907812345', NULL, 'Head', '50000', 'NI001', '01-FEB-06'
from branch e where e.bid = '901';
insert into employee select ref(e), '105', 'New', 'Edinburgh', 'EH2 4AB', 'Mr', 'John William', 01312031990, 0790231455107701234567, '101', 'Manager', '40000', 'NI010', '04-MAR-07'
from branch e where e.bid = '901';
insert into employee select ref(e), '108', 'Old', 'Edinburgh', 'EH9 4BB', 'Mr', 'Mark Slack', 01312102211, NULL, '105', 'accountant', '30000', 'NI120', '01-Feb-09'
from branch e where e.bid = 901;
insert into employee select ref(e), '804', 'Adam', 'Edinburgh', 'EH1 6EA', 'Mr', 'Jack Smith', 01311112223, 0781209890, '801', 'Leader', '35000', 'NI810', '05-Feb-08'
from branch e where e.bid = 908;
select e_bid from EMPLOYEE where e_bid = '901'; //query I'm using
I am trying to query the employee table for the bid's that are referenced to branch table, but when I run the worksheet the script output tells me that I have no rows selected.
e_bid is a reference to the branch object and does not refer to the bID column contained in the object. You want:
SELECT e_bid
FROM EMPLOYEE
WHERE DEREF(e_bid).bID = 901;
I see no reason why your BRANCH_TYPE needs to contain a self reference (and when you set it you are creating a duplicate of the branch so there will be one instance where branch_id is NULL and another where it refers to itself).
You are repeating several structures across the tables and a better structure might be:
DROP SEQUENCE EMPLOYEES__ID__SEQ;
DROP TABLE EMPLOYEES;
--DROP TYPE EMPLOYEE_TYPE;
--DROP TABLE BRANCHES;
--DROP TYPE BRANCH_TYPE;
--DROP TYPE PHONENUMBER_TABLE_TYPE;
--DROP TYPE PHONENUMBER_TYPE;
--DROP TYPE ADDRESS_TYPE;
CREATE TYPE ADDRESS_TYPE AS OBJECT(
street varchar2(20),
city varchar2(20),
p_code varchar2(8)
);
/
CREATE TYPE PHONENUMBER_TYPE AS OBJECT(
international varchar2(4),
area varchar2(5),
local varchar2(8)
);
/
CREATE TYPE PHONENUMBER_TABLE_TYPE AS TABLE OF PHONENUMBER_TYPE;
/
CREATE TYPE BRANCH_TYPE AS OBJECT (
ID number(6),
Address ADDRESS_TYPE,
Phone PHONENUMBER_TYPE
);
/
create table branches of branch_type( ID PRIMARY KEY );
INSERT INTO BRANCHES VALUES (
901,
ADDRESS_TYPE( 'Market', 'Edinburgh', 'EH5 1AB' ),
PHONENUMBER_TYPE( '044', '1311', '235560' )
);
INSERT INTO BRANCHES VALUES (
908,
ADDRESS_TYPE( 'Bridge', 'Glasgow', 'G18 1QQ' ),
PHONENUMBER_TYPE( '044', '1413', '214556' )
);
create type employee_Type as object(
branch ref branch_type,
ID number(8),
address ADDRESS_TYPE,
title varchar2(4),
firstname_surname varchar2(20),
homephone PHONENUMBER_TYPE,
mobiles PHONENUMBER_TABLE_TYPE,
supervisor REF EMPLOYEE_TYPE, -- Change this to a REF
position varchar2(20),
salary number(5),
ninum varchar2(8),
joindate date
);
/
create table employees of employee_Type (
ID PRIMARY KEY
) NESTED TABLE mobiles STORE AS employees_mobiles;
CREATE SEQUENCE employees__id__seq;
insert into employees
select ref(b),
101, -- EMPLOYEES__ID__SEQ.NEXTVAL,
ADDRESS_TYPE( 'Dart', 'Edinburgh', 'EH1 05T' ),
'Mrs',
'Alison Smith',
PHONENUMBER_TYPE( '044', '1312', '125555' ),
PHONENUMBER_TABLE_TYPE(
PHONENUMBER_TYPE( '044', '7705', '623443' ),
PHONENUMBER_TYPE( '044', '7907', '812345' )
),
NULL,
'Head',
50000,
'NI001',
DATE '1906-02-01'
from branches b
where b.id = 901;
insert into employees
select ref(b),
102, -- EMPLOYEES__ID__SEQ.NEXTVAL,
ADDRESS_TYPE('New', 'Edinburgh', 'EH2 4AB'),
'Mr',
'John William',
PHONENUMBER_TYPE(NULL, '0131', '2031990'),
PHONENUMBER_TABLE_TYPE (PHONENUMBER_TYPE('44', '07902', '314551'), PHONENUMBER_TYPE('44', '07701', '234567')),
REF(s),
'Manager',
40000,
'NI010',
DATE '2007-03-04'
from branches b,
employees s
where b.id = 901
and s.id = 101;

How to solve single-row subquery returns more than one row

I have an employee table and it contains salary table. I want to give %10 increase to all current employees. I tried to update all employees' salary dates to specific date but I encountered problem with single-row subquery.
My database like this:
CREATE TYPE TEMPORAL_VARCHAR AS OBJECT (
VALID_TIME_LOWER_BOUND DATE,
VALID_TIME_UPPER_BOUND DATE,
VALUE_PART VARCHAR2(50) );
CREATE TYPE TEMPORAL_NUMBER AS OBJECT (
VALID_TIME_LOWER_BOUND DATE,
VALID_TIME_UPPER_BOUND DATE,
VALUE_PART NUMBER );
CREATE TYPE NAME_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE ADDRESS_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE DEPARTMENT_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE MANAGER_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE SALARY_TYPE AS TABLE OF TEMPORAL_NUMBER;
CREATE TABLE EMPLOYEE (
SSN NUMBER primary key,
NAME NAME_TYPE,
ADDRESS ADDRESS_TYPE ,
BIRTH_DATE DATE,
MANAGER MANAGER_TYPE ,
DEPARTMENT DEPARTMENT_TYPE,
SALARY SALARY_TYPE
)
NESTED TABLE NAME STORE AS NAME_TABLE,
NESTED TABLE ADDRESS STORE AS ADDRESS_TABLE,
NESTED TABLE MANAGER STORE AS MANAGER_TABLE,
NESTED TABLE DEPARTMENT STORE AS DEPARTMENT_TABLE,
NESTED TABLE SALARY STORE AS SALARY_TABLE
;
How to solve this problem? I tried to do this
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = '11.16.2015'
WHERE SAL.VALID_TIME_UPPER_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY');
1st it can be duplicate
2nd see sample here
3rd in your code you need bring the where condition into select
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
WHERE ssn in (SELECT ssn FROM EMPLOYEE e
WHERE to_date('01.01.2015','mm.dd.yyyy') in (
SELECT VALID_TIME_UPPER_BOUND FROM TABLE(e.salary)
)
)
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = to_date('01.01.9999','mm.dd.yyyy')
test data
INSERT INTO EMPLOYEE(SSN, salary) values (1, SALARY_TYPE ());
INSERT INTO EMPLOYEE(SSN, salary) values (2, SALARY_TYPE ());
INSERT INTO EMPLOYEE(SSN, salary) values (3, SALARY_TYPE ());
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 1)
VALUES (to_date('01.01.2005','mm.dd.yyyy'), to_date('01.01.2015','mm.dd.yyyy'), 1);
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 2)
VALUES (to_date('02.02.2005','mm.dd.yyyy'), to_date('02.02.2015','mm.dd.yyyy'), 2);
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 3)
VALUES (to_date('03.03.2005','mm.dd.yyyy'), to_date('03.03.2015','mm.dd.yyyy'), 3);
p.s do you really need the complexity?
I solved my problem using iteration like this
BEGIN
FOR employees IN (SELECT SSN FROM EMPLOYEE)
LOOP
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
WHERE E.SSN = employees.SSN
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = '11.16.2015'
WHERE SAL.VALID_TIME_UPPER_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY');
END LOOP;
END;