How do I insert data into object tables that have refs to others? - sql

I'm new in Oracle and I really don't have a clear idea how to do this.
The database is this one...
CREATE OR REPLACE TYPE personUdt4 AS OBJECT(
pid varchar(11),
firstName varchar(20),
lastName varchar(20),
dob date)
NOT FINAL;
/
CREATE OR REPLACE TYPE locationUdt4 AS OBJECT(
street varchar(30),
bldg varchar(5),
room varchar(5))
NOT FINAL;
/
CREATE TYPE departmentUdt4;
/
CREATE TYPE studentUdt4;
/
CREATE TYPE facultyUdt4;
/
CREATE OR REPLACE TYPE campusClubUdt4 AS OBJECT(
cId number,
name varchar(50),
location locationUdt4,
phone varchar(12),
advisor REF facultyUdt4,
members REF studentUdt4)
NOT FINAL;
/
CREATE OR REPLACE TYPE facultyUdt4 UNDER personUdt4(
rank varchar(10),
advisorOf REF campusClubUdt4,
worksIn REF departmentUdt4,
chairOf REF departmentUdt4)
NOT FINAL;
/
CREATE OR REPLACE TYPE studentUdt4 UNDER personUdt4(
status varchar(10),
memberOf REF campusClubUdt4,
major REF departmentUdt4)
NOT FINAL;
/
CREATE OR REPLACE TYPE studentUdtList4 AS VARRAY(1000) of studentUdt4;
/
CREATE OR REPLACE TYPE facultyUdtList4 AS VARRAY(50) of facultyUdt4;
/
CREATE OR REPLACE TYPE departmentUdt4 AS OBJECT(
code varchar(3),
name varchar(40),
deptChair REF facultyUdt4,
MEMBER FUNCTION getStudents RETURN studentUdtList4,
MEMBER FUNCTION getFaculty RETURN facultyUdtList4)
NOT FINAL;
/
CREATE TYPE BODY departmentUdt4 as
member function getStudents return studentUdtList4
end func;
member function getFaculty return facultyUdtList4
end func;
end;
/
CREATE TABLE person4 OF personUdt4(
primary key (pid));
/
CREATE TABLE faculty4 OF facultyUdt4;
/
CREATE TABLE student4 OF studentUdt4;
/
CREATE TABLE department4 OF departmentUdt4(
primary key (code));
/
CREATE TABLE campusClub4 OF campusClubUdt4(
primary key (cid)
);
INSERT INTO student4
(pid, firstname, lastname, dob, status, memberOf, major)
VALUES
('10','alex','smith','31-may-98','FRESH', '10', '11');
COMMIT;
It'll be great if someone can help me D:

(This is all based on my very limited knowledge of Oracle's object-relational technology. Some of it may be wrong, and there's likely a simpler way to do this.)
As I understand it, a REF must point to an actual row. You must create some data before you can create some data. Since there are so many circular references you'll have to go back later and update everything. But hopefully this is enough to at least get you started.
--Create some rows to reference.
insert into campusClub4(cid) values(1);
insert into department4(code) values('A');
--Insert regular columns first.
insert into student4(pid, firstName, lastName, dob, status)
values('10', 'alex', 'smith', to_date('31-MAY-1998', 'DD-MON-YYYY'), 'FRESH');
--Add references with an update.
update student4
set memberOf = (select ref(campusClub) from campusClub4 campusClub where cid = 1)
,major = (select ref(department) from department4 department where code = 'A')
where pid = '10';
--Verify data
select pid, firstname, lastname, dob, status, deref(memberOf), deref(major) from student4;
--This would be a simpler method, but it doesn't work and I don't understand why.
insert into student4(pid, firstName, lastName, dob, status)
values('10', 'alex', 'smith', to_date('31-MAY-1998', 'DD-MON-YYYY'), 'FRESH'
,(select ref(campusClub) from campusClub4 campusClub where cid = 1)
,(select ref(department) from department4 department where code = 'A')
);
But I strongly recommend that you NEVER DO THIS. Inserting data into a table should not be this difficult. Object Relational databases are probably a bad idea. And Oracle's implementation of it sucks. You'll get ORA-600 errors and "invalid" tables all over the place with this stuff (e.g. I just got an ORA-600 from cross joining campusClub4 and department4 with only one row in each). And nobody will know how to use your data.

Related

How to overcome a persistent oracle 'invalid identifier' error on a basic insert?

I am trying to create a basic table using subtypes and insert some data into this in Oracle Express 11g.
My table is successfully created but i am having issues with inserting data.
The result of my insert statement always throws back an error 'SQL Error: ORA-00904: "BRANCH_PHONE": invalid identifier'.
The column which shows up in the error message is always the column which is at the end of the insert statement, despite the column existing in the table. I have tried the following code:
create type addressType as object(
street varchar2(20),
city varchar2(20),
postCode varchar2(8))
not final
/
create type branchType as object(
branchID int,
branch_address addressType,
branch_phone int(11))
not final
/
create table Branch of branchType(
constraint branch_pk primary key(branchID));
/
insert into Branch values (
branchID('2364'),
addressType('12 Rooster','Atlantis','A13 4UG'),
branch_phone('01316521311'));
I would really appreciate any ideas.
I made some changes, including changing the branch_phone to varchar2. A Phone number, while is "numbers" is not a data type of number. it is a string of characters. Also you were passing branchID as a string, but you are declaring it as a number, so changed that also. BranchID and branch_phone are primitive data types, so no constructor needed.
create type addressType as object(
street varchar2(20),
city varchar2(20),
postCode varchar2(8))
not final
/
create type branchType as object(
branchID int,
branch_address addressType,
branch_phone varchar2(11))
not final
/
create table Branch of branchType(
constraint branch_pk primary key(branchID));
/
insert into Branch values (
branchtype(2364,
addressType('12 Rooster','Atlantis','A13 4UG'),
'01316521311') )

SuperType Table of subtype objects not showing added attributes

I am trying to make a supertype table of objects that holds subtype objects, but the bottom line insert once ran shows the first two attributes SSN and name as inserted. Is Oracle Express just broken these days? or is there something wrong in my code?
create or replace type PersonType as object (
SSN number (9),
name varchar2(30))
Instantiable
NOT Final;
create or replace type TenantType under PersonType (
aptNum REF ApartmentType,
phone number(10),
car varchar2(15),
contract varchar2(10));
Instantiable
Final;
create or replace type EmployeeType under PersonType (
empId number(4),
empAdr varchar2(40));
Instantiable
Final;
create table P1 of PersonType (
constraint P1_SSN_pk Primary Key (SSN));
insert into P1 values(TenantType(956785252, 'Jerry Wilson', (select ref(a) from A1 a where aptNum = 110), 8015167895, 'Toyota', '8 months'));
If you run simple select you see common values of supertype. When creating types you can add member function to display subtypes in different ways or you can use treat():
select treat(value(p) as tenanttype) from p1 p where p.ssn = 956785252
You have typos (unnecessary semicolons in type definitions) and missing definition of ApartmentType and table a1, so here are my test data: dbfiddle
And here are examples of mentioned member function show(): Inheritance in SQL Object Types

Displaying Oracle SQL Types

I am having a hard time getting an output from a table.
Here is the table creation
CREATE OR REPLACE TYPE FULL_MAILING_ADDRESS AS OBJECT
( STREET VARCHAR2(80),
CITY VARCHAR2(80),
STATE CHAR(2),
ZIP VARCHAR2(10));
CREATE TABLE CUSTOMER
(
FULL_ADDRESS FULL_MAILING_ADDRESS
);
INSERT INTO CUSTOMER VALUES (FULL_MAILING_ADDRESS('55 SOUTH','ARLINGTON','VA','2222'));
when I do select on the table I don't get the values instead I get
[ORACLE.FULL_MAILING_ADDRESS]

Adding Constraints to VARRAY UDT inside a Table in PLSQL

I'm stuck figuring out how to add some constraints to the attributes of my UDTs.
Here's my situation. I've got a UDT that represents the daily number of hours an employee should work (forgive me for using Italian names).
CREATE OR REPLACE TYPE TURNO_GIORNALIERO AS OBJECT(
GIORNO VARCHAR(15),
ORA_INIZIO DATE,
NUMERO_ORE NUMBER,
MEMBER FUNCTION getOreLavoro RETURN NUMBER
);
Then I defined new Type as a VARRAY(5) of TURNO_GIORNALIERO, named TURNI_SETTIMANALI (that is a Varray containing the number of hours an employee should work for each day of the week).
CREATE OR REPLACE TYPE TURNI_SETTIMANALI AS VARRAY(5) OF TURNO_GIORNALIERO;
In the end, I've created the table that contains TURNI_SETTIMANALI.
CREATE TABLE TURNO_LAVORO(
ID_TURNO CHAR(9) PRIMARY KEY,
TURNO TURNI_SETTIMANALI NOT NULL,
);
What I want to do is to add a constraint to the table TURNO_LAVORO in order to check if NUMERO_ORE (defined in TURNO GIORNALIERO) is greater than 5.
Could someone please help me? I've tried several solutions but nothing worked.
I doubt it is possible in check constraint. Documentation says:
Conditions of check constraints cannot contain the following
constructs:
Calls to user-defined functions
Nested table columns or attributes
You could use trigger however. Test types and table:
create or replace type daily_cycle
as object(day varchar(15), hour_start date, hour_count number);
create or replace type week_cycle
as varray(5) of daily_cycle;
create table test(id int, shift week_cycle);
Trigger:
create or replace trigger hour_check before insert on test for each row
begin
for i in 1..:new.shift.count() loop
if :new.shift(i).hour_count < 5 then
raise_application_error(-20001,'hours less than 5');
end if;
end loop;
end;
First insert works, second no:
insert into test values (1,
week_cycle(daily_cycle('a', date '2017-12-01', 5),
daily_cycle('b', date '2017-12-02', 8) ) );
insert into test values (2,
week_cycle(daily_cycle('a', date '2017-12-03', 3),
daily_cycle('b', date '2017-12-04', 12),
daily_cycle('b', date '2017-12-05', 7) ) );

ORA-00936: missing expression error when inserting values

I spend lot of time searching where i made the mistake but i was unable to find it when its going to insert the last record there is a error message showing "ORA-00936: missing expression" How to solve this please help me
create type pearson_types as object(
name varchar2(50),
sysID char(6)
)NOT FINAL;
create type doctor_types under pearson_types(
regNo char(10),
specialization varchar2(25)
)
create table doctor of doctor_types(
regNo primary key
)
create type hospVisits_types as object(
hosChg float,
vDate varchar2(20),
refDoc REF doctor_types,
docChg float
)
create type hospvisits_tbl_types as table of hospVisits_types
create type phone_arr as VARRAY(3) of char(10)
create type patient_types under pearson_types
(
id char(10),
dob varchar(20),
phone phone_arr,
hospVisits hospvisits_tbl_types
)
create table patients of patient_types(
id primary key
)nested table hospVisits store as Hospital_tables
alter table Hospital_tables add scope for (refDoc) is doctor
insert into doctor values ('Dr.k.perera','D001','1223441234','Gynecologist');
insert into doctor values ('Dr.p.weerasingha','D002','1234421131','Dermatalogist');
insert into doctor values ('Prof .S. Fernando','D003','2342111322','Pediatrician');
insert into doctor values ('Dr.k.Sathgunanathan','D004','2344114344','Pediatrician');
insert into patients values('Sampath Weerasingha','P001','732821122V','23-JAN-73',phone_arr('0332124222'),hospvisits_tbl_types(hospVisits_types(50.00,'24-MAY-06',select ref (a) from doctor a where a.regNo='1223441234',500.00)))
Add parentheses to SELECT statements inside a SQL statement:
insert into patients values(
'Sampath Weerasingha','P001','732821122V','23-JAN-73',phone_arr('0332124222'),
hospvisits_tbl_types(hospVisits_types(50.00,'24-MAY-06',
( -- ADD ME
select ref (a) from doctor a where a.regNo='1223441234'
) -- ADD ME
,500.00))
);