Using objects to insert variable array into nested table - oracle

I have a series of tables and objects I have defined. I have an object nested table that I am trying to insert values into. The values are in the form of a variable array but I don't know how to insert them. my tables and code are as follows.
Table wu.classes
crn number(5)
department varchar2(8)
title carchar2(25)
Table wu.students
student_id char(11)
name varchar2(10)
dept varchar2(8)
advisor varchar(10)
classes wu.classes_va
wu.classes_va varray(5) of number (5)
create type classes_ty as object(crn varchar2(5),department varchar2(8), coursetitle varchar2(25)
create table classes_ot of classes_ty;
insert into classes_ot select crn,department,title from wu.classes;
create or replace type classes_ref_ty as table of ref classes_ty;
create table student_plus(student# varchar2(11),student_name varchar2(10),major varchar2(8), advisor (10), enrolled classes_ref_ty) nested table enrolled store as classes_ref_ty_tab;
Problem here (I need to loop through to fill the table but I just need to know how to do it for one values and i can figure the rest out):
begin
insert into student_plus values('700-123-948','Hooker','CS','VanScoy',classes_ref_ty();
insert into table(select enrolled from student_plus where student#='700-123-948')
select ref(c) from classes_ot c where ???
end;
/
I don't know how to access the variable array and use it with the classes_ref_ty.

Related

Oracle Object Type and Object Table

I have created an object type and a table. I would like to know how select, insert, update and delete operation on it.
create table employee_info (
empid number,
emp_name varchar2(50),
department varchar2(20),
designation varchar2(50),
salary number
);
create type employee_info_obj is object (
empid number,
department varchar2(50),
designation varchar2(50),
salary number
);
create type employee_info_obj_t is
table of employee_info_obj ;
You have only created an object type and an unrelated database table. If you want a database table based on the type, you need to create one:
create table employee_info of employee_info_obj;
While it can be nice in certain programming scenarios to have a type synced to a table, there are some downsides such as it being harder to add columns later, and third party tool support since the object table will not be listed in user_tables but only in user_object_tables and user_all_tables, so I would question the usefulness of this approach.
dbFiddle

Can you use Object Types in Procedures in Oracle PL/SQL?

Hello fellow programmers. Im currently working on a webshop database for my studying program. Currently im trying to make a procedure which creates an order in the orders table for a customer when he/she/it is beeing created. I am also thinking of putting this into a constructor but since i want to use this functionality twice once when the order reaches a certain status and after creation i want to bundle this functionality in a procedure. I have spend nearly 8 hours of research and testing on this but since the feedback from oracle db on my code is 0 to nothing i cant figure out what is wrong. When i create the procedure it is not flagged as valid and i cant even see the parameters in the parameters tab when i click on the procedure. I hope the code formatting works this is my first post..
This are the types order and Customer which hold a REF to each other
CREATE TYPE ORDER_TYPE AS OBJECT(
Order_Id NUMBER,
Date_of_Creation DATE,
Items ITEM_LIST,
Status REF STATUS_TYPE,
Customer REF CUSTOMER_TYPE
);
CREATE TYPE CUSTOMER_TYPE AS OBJECT(
Customer_Id NUMBER,
Email VARCHAR2(254),
User_Name VARCHAR2(50),
Password VARCHAR2(20),
First_Name VARCHAR2(50),
Last_Name VARCHAR2(50),
Address ADDRESS_TYPE,
Shopping_Cart REF ORDER_TYPE
);
CREATE TABLE Orders OF ORDER_TYPE(Status SCOPE IS Order_Status NOT NULL, Customer NOT NULL)
NESTED TABLE Items STORE AS ORDER_ITEMS_NT_TAB;
ALTER TABLE Orders ADD CONSTRAINT PK_Orders PRIMARY KEY(Order_Id);
CREATE TABLE Customers OF CUSTOMER_TYPE(Customer_Id PRIMARY KEY,
Email NOT NULL,
User_Name NOT NULL,
Password NOT NULL,
First_Name NOT NULL,
Last_Name NOT NULL,
Address NOT NULL);
This is the procedure code. The input should be the customer created or updated. Then i want to insert a new order, i still have to change the id field to guid or uuid so every order will be unique but for testing purpose i just used 1. The item list should be empty at first and the status of the order should be status 1 which stands for "Shopping_Cart" this means that the order is still beeing created and should be displayed as shopping cart in the browser later on. After the insert i want to return the inserted row with the returning into statement so i cant update the customer and set the ref of his shopping cart to the new inserted order. I cant figure out whats wrong im still working on it but i would be greatful for any help.
CREATE PROCEDURE create_customer_order(customer IN CUSTOMER_TYPE) AS
DECLARE
shopping_c NUMBER;
BEGIN
INSERT INTO ORDERS
VALUES(1,CURRENT_DATE ,NEW ITEM_LIST(),(SELECT REF(os) FROM ORDER_STATUS os WHERE VALUE(os).STATUS_ID = 1),REF(customer))
RETURNING Order_Id INTO shopping_c;
UPDATE CUSTOMERS c
SET c.SHOPPING_CART = (SELECT REF(o) FROM ORDERS o WHERE o.ORDER_ID = shopping_c)
WHERE c.CUSTOMER_ID = customer.CUSTOMER_ID;
END;
Feel free to ask questions if something is not clear. Cheers!
I will include a working example.
But first, you did not provide all types. So i assumed them.
I see you have types that refer to eachother. This is basically not a good idea.
For storing data, you could use object types, but you could also use normal data types like number/varchar2. You would need tables orders/order_items/customers. If you want to make changes to the customer_type and your table is already populated with data, changing the type is difficult (what to do with the old data?).
But to come back at your question, here is a working example.
drop type customer_type force;
drop type order_type force;
drop type address_Type force;
drop type status_type force;
drop type item_list force;
create type STATUS_TYPE as object (
status number
);
create type ADDRESS_TYPE as object (
street varchar2(100)
);
create type ITEM_LIST as object (
itemname varchar2(100)
);
CREATE TYPE ORDER_TYPE AS OBJECT(
Order_Id NUMBER,
Date_of_Creation DATE,
Items ITEM_LIST,
Status REF STATUS_TYPE,
Customer REF CUSTOMER_TYPE
);
CREATE TYPE CUSTOMER_TYPE AS OBJECT(
Customer_Id NUMBER,
Email VARCHAR2(254),
User_Name VARCHAR2(50),
Password VARCHAR2(20),
First_Name VARCHAR2(50),
Last_Name VARCHAR2(50),
Address ADDRESS_TYPE,
Shopping_Cart REF ORDER_TYPE
);
alter type order_type compile;
drop table orders;
CREATE TABLE Orders (id number, Status status_type , Customer CUSTOMER_TYPE);
CREATE OR REPLACE PROCEDURE create_customer_order(p_customer IN CUSTOMER_TYPE) AS
shopping_c NUMBER;
BEGIN
dbms_output.enable(null);
INSERT INTO ORDERS (id, status, customer)
VALUES (1, null, p_customer)
RETURNING id INTO shopping_c;
commit;
dbms_output.put_line('id='||shopping_c);
END;
/
--Test
declare
l_customer customer_type;
begin
l_customer := customer_type (Customer_Id => 1
, email=>'a#b.org'
, user_name=>'test'
, password=>'DoyouReallyWantThis'
, first_name=>'first'
, last_name =>'last'
, address=>null --for simplicity
, shopping_cart=>null --for simplicity
);
create_customer_order(p_customer => l_customer);
end;
/
thanks for your answer.. It did not work for me and you also missed the update part in the procedure but still thank you for the effort. i managed to get the procedure working by running every code piece step by step and watching if it fails. Feels like javascript to me lol. I discovered for some reason i cant explain that you cant declare variables under the declare statement and you cant use defined object types as parameters. i could not find anything about it in the documentation. to everyone still interested how i solved the problem this is the code.
CREATE OR REPLACE PROCEDURE create_customer_order(p_customer_id IN NUMBER)
AS
BEGIN
INSERT INTO ORDERS
VALUES(1, CURRENT_DATE, NEW ITEM_LIST(),(SELECT REF(os) FROM ORDER_STATUS os WHERE os.STATUS_ID = 1),(SELECT REF(c) FROM CUSTOMERS c WHERE c.CUSTOMER_ID = p_customer_id));
UPDATE CUSTOMERS c
SET c.SHOPPING_CART = (SELECT REF(o) FROM ORDERS o WHERE DEREF(o.Customer).Customer_Id = p_customer_id AND DEREF(o.STATUS).Status_Id = 1 )
WHERE c.CUSTOMER_ID = p_customer_id;
END;

Insertion in Nested Tables on Oracle DB

I am a new learner of PL/SQL databases,A kind of exercise given to apply database on apex.oracle.com with given sequence.Then I have created tables but when it comes to fill tables with the insertion code as follows,Application has given error,Would you mind if I need your assistance
Thanks in Advance,
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 );
Time-related attributeshave defined with the code as follows;
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
;
And the insertion that I am inteded to do
INSERT INTO EMPLOYEE VALUES
(101,
NAME(TEMPORAL_VARCHAR('23.11.2005','12.31.9999','James Brown')),
ADDRESS(TEMPORAL_VARCHAR('23.11.2005','12.31.9999','BUCA, IZMIR')),
'23.10.1986',
MANAGER(TEMPORAL_VARCHAR('23.11.2005','12.31.9999','Mike White')),
DEPARTMENT(TEMPORAL_VARCHAR('23.11.2005','12.31.9999','DEPT_ID05')),
SALARY(TEMPORAL_NUMBER('23.11.2005',’12.31.9999’, 250000))
);
And the error message I recieved is :
ORA-00904: "SALARY": invalid identifier
There are spaces before _ here
CREATE TYPE MANAGER _TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE SALARY _TYPE AS TABLE OF TEMPORAL_NUMBER;
DEPARTMENT DEPARTMENT _TYPE
A comma is missing after DEPARTMENT _TYPE
try this solution:
'alter session set NLS_DATE_FORMAT='DD.MM.YYYY';'
----------------------------------------------------
INSERT INTO EMPLOYEE VALUES
(101,
NAME_TYPE(TEMPORAL_VARCHAR('23.10.1986','09.09.9999','James Brown')),
ADDRESS_TYPE(TEMPORAL_VARCHAR('15.12.2009','09.09.9999','BUCA')),
'23.10.1986',
MANAGER_TYPE(TEMPORAL_VARCHAR('24.05.2008','09.09.9999','Mike White')),
DEPARTMENT_TYPE(TEMPORAL_VARCHAR('03.01.2012','09.09.9999','DEPT_ID05')),
SALARY_TYPE(TEMPORAL_NUMBER('01.01.2003','09.09.9999', 3200))
);

What is the purpose of "RETURN AS VALUE" in NESTED TABLES (Oracle 9i)

Is there a specific case, when i should use RETURN AS VALUE?
Normally i use only NESTED TABLE xxx STORE AS xxx
For example:
CREATE OR REPLACE TYPE address_t AS OBJECT (
ADDID NUMBER(10,0),
STREET VARCHAR2(40),
ZIP VARCHAR2(5),
CITY VARCHAR2(40)
)
/
CREATE OR REPLACE TYPE addresses_nt AS TABLE OF address_t
/
CREATE OR REPLACE TYPE invoicepos_t AS OBJECT (
ARTID NUMBER(10,0),
AMOUNT NUMBER(10,0)
)
/
CREATE OR REPLACE TYPE invoicepos_nt AS TABLE OF invoicepos_t
/
CREATE OR REPLACE TYPE customer_t AS OBJECT (
CUSID NUMBER(10,0),
FIRSTNAME VARCHAR2(30),
LASTNAME VARCHAR2(30),
ADDRESSES addresses_nt
)
/
CREATE OR REPLACE TYPE invoice_t AS OBJECT (
INVOICEID NUMBER(10,0),
CUSTOMER REF customer_t,
ADDID NUMBER(10,0),
POSITIONS invoicepos_nt
)
/
CREATE TABLE customer OF customer_t
NESTED TABLE ADDRESSES STORE AS all_adresses RETURN AS VALUE
/
CREATE TABLE invoices OF invoice_t
NESTED TABLE POSITIONS STORE AS all_invoicepos RETURN AS VALUE
/
As far as I can tell, the only difference is that LOCATORs are a bit faster than VALUEs. But that doesn't make sense and I'm hoping somebody will prove me wrong; there's almost never a "fast=true" switch.
According to the SQL Language Reference:
RETURN [AS] Specify what Oracle Database returns as the result of a query.
VALUE returns a copy of the nested table itself.
LOCATOR returns a collection locator to the copy of the nested table.
The locator is scoped to the session and cannot be used across sessions. Unlike a LOB locator, the collection locator cannot be used to modify the collection instance.
This implies that LOCATORs are read-only. But on 11gR2 a LOCATOR can still be modified.
The Object Relational Developer's Guide also discusses LOCATORs, but does not mention any downsides to using them.
Sample Schema
CREATE OR REPLACE TYPE invoicepos_t AS OBJECT (
ARTID NUMBER(10,0),
AMOUNT NUMBER(10,0)
)
/
CREATE OR REPLACE TYPE invoicepos_nt AS TABLE OF invoicepos_t
/
create table invoices_val
(
INVOICEID NUMBER,
POSITIONS invoicepos_nt
)
NESTED TABLE POSITIONS STORE AS all_invoicepos_val RETURN AS VALUE
/
create table invoices_loc
(
INVOICEID NUMBER,
POSITIONS invoicepos_nt
)
NESTED TABLE POSITIONS STORE AS all_invoicepos_loc RETURN AS locator
/
insert into invoices_val values(1, invoicepos_nt(invoicepos_t(1,1)));
insert into invoices_loc values(1, invoicepos_nt(invoicepos_t(1,1)));
insert into invoices_def values(1, invoicepos_nt(invoicepos_t(1,1)));
commit;
Compare performance and funcionality
--Value: 1.0 seconds
declare
v_positions invoicepos_nt;
begin
for i in 1 .. 10000 loop
select positions
into v_positions
from invoices_val;
end loop;
v_positions.extend;
v_positions(2) := invoicepos_t(3,3);
update invoices_val set positions = v_positions;
end;
/
--Locator: 0.8 seconds
declare
v_positions invoicepos_nt;
begin
for i in 1 .. 10000 loop
select positions
into v_positions
from invoices_loc;
end loop;
v_positions.extend;
v_positions(2) := invoicepos_t(3,3);
update invoices_loc set positions = v_positions;
end;
/

I am trying to use a Subtype Object in place of a Supertype object but it is not working?

I have created two objects T_PERSONS,T_BUSINESS_PERSON where T_BUSINESS PERSON is a subtype and T_PERSONS is a supertype.
---Creating T_PERSONS OBJECT---
CREATE OR REPLACE
TYPE T_PERSONS AS OBJECT
( id integer,
first_name varchar2(10),
last_name varchar2(10),
dob DATE,
phone varchar2(12),
address t_address,
) NOT FINAL;
---Creating T_BUSINESS_PERSON OBJECT---
CREATE TYPE t_business_person UNDER t_persons
(title varchar2(20),
company varchar2(20)
);
Now I created an object table object_customers
CREATE TABLE object_customers OF t_persons
INSERTING DATA INTO object_customers
INSERT INTO object_customers VALUES
(t_persons(1,'Jason','Bond','03-APR-1955','800-555-1211',
t_address('21 New Street','Anytown','CA','12345')
));
in this case,data has been inserted properly
INSERT INTO object_customers VALUES
(t_business_person(2,'Steve','Edwards','03-MAR-1955','800-555-1212',
t_address('1 Market Street','Anytown','VA','12345'),'Manager','XYZ Corp'
));
Now in this case an error has occured
Error-attribute or element value is larger than specified in type.
Please Help.
The second insertion will work only if you create the table as follows:
CREATE TABLE object_customers OF t_business_person;
Click here to read more about NOTFINAL clause.

Resources