Object type
create or replace TYPE "TYPE_FE_FEE_DETAIL" AS OBJECT
(
FE_AMOUNT VARCHAR2(25),
CURR_ID VARCHAR2(5),
PROFILE_TYPE VARCHAR2(1),
ISO_CODE VARCHAR2(25)
);
create or replace TYPE "TYPE_TB_FE_FEE_DETAIL" AS TABLE OF type_fe_fee_detail;
We have a view with two columns where the second column is of OBJECT TYPE and has data like
EPAYPROD_M3.TYPE_TB_FE_FEE_DETAIL(EPAYPROD_M3.TYPE_FE_FEE_DETAIL('10', '1', '1', '818'))
I need to insert these four values into a table which has four separate columns. I am having in trouble doing so.
TYPE_TB_FE_FEE_DETAIL is a nested table. To get the attribute values, unnest it.
You can do this with the table operator:
create or replace TYPE "TYPE_FE_FEE_DETAIL" AS OBJECT
(
FE_AMOUNT VARCHAR2(25),
CURR_ID VARCHAR2(5),
PROFILE_TYPE VARCHAR2(1),
ISO_CODE VARCHAR2(25)
);
/
create or replace TYPE "TYPE_TB_FE_FEE_DETAIL" AS TABLE OF type_fe_fee_detail;
/
with rws as (
select type_tb_fe_fee_detail(type_fe_fee_detail('10', '1', '1', '818')) obj
from dual
)
select t.*
from rws r, table ( r.obj ) t;
FE_AMOUNT CURR_ID PROFILE_TYPE ISO_CODE
10 1 1 818
Related
I have been trying to get this thing working for a few day now (foreign key) and it just don't work, and feel like every solution I used don't work, so i'm asking here to learn what was the problem and how to fix it
Table creation :
CREATE TABLE CUSTOMER
(
Customer_ID varchar(255) NOT NULL,
Customer_Name varchar(50),
Customer_Gender varchar(10),
Customer_DOB varchar(20) ,
CONSTRAINT CUSTOMER_PK PRIMARY KEY(Customer_ID)
) ;
CREATE TABLE PAYMENT
(
Payment_ID varchar(255) NOT NULL,
Cust_ID varchar(255),
Payment_Method varchar(30),
Payment_Date varchar(20),
Payment_Total NUMBER(10,2) ,
CONSTRAINT PAYMENT_PK PRIMARY KEY(Payment_ID),
CONSTRAINT fk_customer FOREIGN KEY(Cust_ID) REFERENCES CUSTOMER(Customer_ID)
) ;
Inserting values :
INSERT INTO CUSTOMER VALUES ('1277','Jenny','Female', ( TO_Date ( '03/04/1988' , 'DD/MM/yyyy')));
INSERT INTO CUSTOMER VALUES ('3423','Bryan','Male', ( TO_Date ( '15/06/1990' , 'DD/MM/YYYY')));
INSERT INTO CUSTOMER VALUES ('4385','Mohd Shafik','Male',( TO_Date ( '20/08/1993' , 'DD/MM/YYYY')));
INSERT INTO PAYMENT VALUES ('24P','Cash', ( TO_Date ( '11/02/2022' , 'DD/MM/YYYY')),24.50);
INSERT INTO PAYMENT VALUES ('09p','Online Transfer', ( TO_Date ( '08/04/2022' , 'DD/MM/YYYY')),25.00);
INSERT INTO PAYMENT VALUES ('10P','Cash', ( TO_Date ( '08/07/2022' , 'DD/MM/YYYY')),22.50);
The foreign keys are now working , but just for life of me can't figure out why the it spits out ORA-00947: not enough values and
ORA-01400: cannot insert NULL into ("SQL_GUUNNGDQAOXJVYPBKNMILVXJR"."PAYMENT"."PAYMENT_ID") ORA-06512: at "SYS.DBMS_SQL", line 1721
Also, Please explain to me how references works, i read a few places but they use words that just confuse me. Please and thank you!
Use DATE data types to store date values (and VARCHAR2 instead of VARCHAR) in your tables:
CREATE TABLE CUSTOMER(
Customer_ID varchar2(255) NOT NULL,
Customer_Name varchar2(50),
Customer_Gender varchar2(10),
Customer_DOB DATE,
CONSTRAINT CUSTOMER_PK PRIMARY KEY(Customer_ID)
);
CREATE TABLE PAYMENT(
Payment_ID varchar2(255) NOT NULL,
Cust_ID varchar2(255),
Payment_Method varchar2(30),
Payment_Date DATE,
Payment_Total NUMBER(10,2) ,
CONSTRAINT PAYMENT_PK PRIMARY KEY(Payment_ID),
CONSTRAINT fk_customer FOREIGN KEY(Cust_ID) REFERENCES CUSTOMER(Customer_ID)
);
Then name the columns in your INSERT statements:
INSERT INTO CUSTOMER (
customer_id, customer_name, customer_gender, customer_dob
) VALUES (
'1277','Jenny','Female', TO_Date('03/04/1988', 'DD/MM/yyyy')
);
INSERT INTO CUSTOMER (
customer_id, customer_name, customer_gender, customer_dob
) VALUES (
'3423','Bryan','Male', TO_Date('15/06/1990', 'DD/MM/YYYY')
);
INSERT INTO CUSTOMER (
customer_id, customer_name, customer_gender, customer_dob
) VALUES (
'4385','Mohd Shafik','Male', TO_Date('20/08/1993' , 'DD/MM/YYYY')
);
Then for the PAYMENT inserts, you have 5 columns in the table but only 4 pieces of data being inserted:
INSERT INTO PAYMENT (
payment_id, payment_method, payment_date, payment_total
) VALUES (
'24P','Cash', TO_Date('11/02/2022', 'DD/MM/YYYY'),24.50
);
INSERT INTO PAYMENT (
payment_id, payment_method, payment_date, payment_total
) VALUES (
'09p','Online Transfer', TO_Date( '08/04/2022' , 'DD/MM/YYYY'),25.00
);
INSERT INTO PAYMENT (
payment_id, payment_method, payment_date, payment_total
) VALUES (
'10P','Cash', TO_Date('08/07/2022', 'DD/MM/YYYY'),22.50
);
You have not provided a Cust_ID value so it will default to NULL in those rows.
If you want to provide a Cust_ID then add it to the statement:
INSERT INTO PAYMENT (
payment_id, cust_id, payment_method, payment_date, payment_total
) VALUES (
'ABC', '1277', 'Cash', TO_Date('08/07/2022', 'DD/MM/YYYY'),22.50
);
db<>fiddle here
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY';
CREATE TABLE CUSTOMER
(
Customer_ID varchar(255) NOT NULL,
Customer_Name varchar(50),
Customer_Gender varchar(10),
Customer_DOB DATE ,
CONSTRAINT CUSTOMER_PK PRIMARY KEY(Customer_ID)
) ;
CREATE TABLE PAYMENT
(
Payment_ID varchar(255) NOT NULL,
Customer_ID varchar(255),
Payment_Method varchar(30),
Payment_Date DATE,
Payment_Total NUMBER(10,2) ,
CONSTRAINT PAYMENT_PK PRIMARY KEY(Payment_ID),
CONSTRAINT fk_customer FOREIGN KEY(Customer_ID) REFERENCES CUSTOMER(Customer_ID)
) ;
INSERT INTO CUSTOMER VALUES ('1277','Jenny','Female', ( TO_Date ( '03/04/1988' , 'DD/MM/yyyy')));
INSERT INTO PAYMENT VALUES ('24P','1277','Cash', ( TO_Date ( '11/02/2022' , 'DD/MM/YYYY')),24.50);
SELECT * FROM Customer;
CUSTOMER_ID CUSTOMER_NAME CUSTOMER_GENDER CUSTOMER_DOB
1277 Jenny Female 03-APR-1988
SELECT * FROM payment;
PAYMENT_ID CUSTOMER_ID PAYMENT_METHOD PAYMENT_DATE PAYMENT_TOTAL
24P 1277 Cash 11-FEB-2022 24.5
Are constraints such as primary key, unique, and foreign key inherited in Oracle through UNDER clause?
The UNDER keyword is for type inheritance. Types cannot have unique/relational constraints.
Are constraints such as primary key, unique, and foreign key inherited in Oracle through UNDER clause?
No, because they don't have such constraints so they cannot be inherited.
Consider, if you have the types:
CREATE TYPE type1 IS OBJECT (
type1_value NUMBER(8,0)
) NOT FINAL;
CREATE TYPE type2 UNDER type1 (
type2_value NUMBER(8,0)
);
And create the object tables:
CREATE TABLE table1a OF type1 (
CONSTRAINT table1a__type1_value__pk PRIMARY KEY ( type1_value )
);
CREATE TABLE table1b OF type1 (
CONSTRAINT table1b__type1_value__pk PRIMARY KEY ( type1_value )
);
CREATE TABLE table2a OF type2;
CREATE TABLE table2b OF type2 (
CONSTRAINT table2b__type2_value__pk PRIMARY KEY ( type2_value )
);
Constraint inheritance doesn't happen but, hypothetically, if they were to inherit constraints which constraint should table2a and table2b inherit? There is no way the database could determine whether a constraint should be inherited from table1a or table1b which is why it doesn't happen.
It doesn't make sense to inherit the constraints as the constraints are on the table, and not on the type, and you are inheriting from the type, and not from a table.
To demonstrate that there is no constraint inheritance you can insert some sample data:
INSERT INTO table1a ( type1_value ) VALUES ( 1 );
INSERT INTO table1a ( type1_value ) VALUES ( 2 );
INSERT INTO table1a ( type1_value ) VALUES ( 3 );
We can insert the same data into table1b demonstrating that tables of the same type do not share constraints (otherwise they would also share the same unique index and would not allow duplicate values):
INSERT INTO table1b ( type1_value ) VALUES ( 1 );
INSERT INTO table1b ( type1_value ) VALUES ( 2 );
INSERT INTO table1b ( type1_value ) VALUES ( 3 );
We can insert the same values into table2a, which is a subtype:
INSERT INTO table2a ( type1_value, type2_value ) VALUES ( 1, 1 );
INSERT INTO table2a ( type1_value, type2_value ) VALUES ( 1, 1 );
INSERT INTO table2a ( type1_value, type2_value ) VALUES ( 2, 1 );
And we can, again, insert the same values into table2b, which is also a subtype and has its own independent primary key:
INSERT INTO table2b ( type1_value, type2_value ) VALUES ( 1, 1 );
INSERT INTO table2b ( type1_value, type2_value ) VALUES ( 1, 2 );
INSERT INTO table2b ( type1_value, type2_value ) VALUES ( 2, 3 );
There is no constraint inheritance in object tables.
db<>fiddle here
Update
From comments:
but isn't there a reference type? thing like:
create type Person(
ID varchar(20) primary key,
name varchar(20),
address varchar(20)
) ref from(ID);
You appear to be confusing two things as you can't include a PRIMARY KEY constraint on a type and the syntax is wrong but you can include a REF to another object; however, it is not a referential constraint to a particular table but (from the Oracle documentation):
REF takes as its argument a correlation variable (table alias) associated with a row of an object table or an object view.
So it is more of a pointer data type than a referential constraint.
For example, if you have the table:
CREATE TABLE ref_table (
value REF type1
);
Then you can insert data from any/all four of the tables above:
INSERT INTO ref_table ( value )
SELECT REF(t) FROM table1a t WHERE type1_value = 1 UNION ALL
SELECT REF(t) FROM table1b t WHERE type1_value = 1 UNION ALL
SELECT REF(t) FROM table2a t WHERE type1_value = 2 UNION ALL
SELECT REF(t) FROM table2b t WHERE type1_value = 2;
There is no referential constraint to a particular table; just pointers to objects that are of the type type1 or a sub-type thereof.
If you want, you could (instead) have added a referential constraint on the REF data type:
ALTER TABLE ref_table ADD CONSTRAINT ref_table__value__fk
FOREIGN KEY ( value ) REFERENCES table1a;
Then:
INSERT INTO ref_table ( value )
SELECT REF(t) FROM table1a t WHERE type1_value = 1;
Would work but inserting references from the other tables would fail.
db<>fiddle here
You can inherit REF data types when they are part of an object type but they do not enforce referential integrity as the object they point to could be in any table or column that holds the data type you are pointing to. However, you cannot inherit FOREIGN KEY referential constraints as they are applied to a table and have nothing to do with the object types or inheritance.
Create table A_15006977.vehicle. (
Vin varchar(20) primary key,
Vehicle_type char(20) not null,
Mileage number(20) not null,
Manufacturer char(20) not null
);
Insert all
Into A_15006977.vehicle(vin,vehicle_type,mileage,manufacturer)
values ('tf1bb2ve533093891','panel van',18 325,'man')
A_15006977.vehicle(vin,vehicle_type,mileage,manufacturer)
values
('tf1bb2ve533093822','standard van',79 885,'ford')
Select * from dual;
Create table A_15006977.vehicle (
Vin varchar(20) CONSTRAINT vehicle__vin__pk PRIMARY KEY,
Vehicle_type char(20) CONSTRAINT vehicle__vehicle_type__nn not null,
Mileage number(20) CONSTRAINT vehicle__mileage__nn not null,
Manufacturer char(20) CONSTRAINT vehicle__manufacturer__nn not null
);
Insert all
Into A_15006977.vehicle(vin,vehicle_type,mileage,manufacturer)
VALUES ( 'tf1bb2ve533093891', 'panel van', 18325, 'man' )
INTO A_15006977.vehicle (vin,vehicle_type,mileage,manufacturer)
values ( 'tf1bb2ve533093822', 'standard van', 79885, 'ford' )
SELECT 1 FROM DUAL;
Or:
Insert Into A_15006977.vehicle( vin,vehicle_type,mileage,manufacturer )
SELECT 'tf1bb2ve533093891','panel van', 18325, 'man' FROM DUAL UNION ALL
SELECT 'tf1bb2ve533093822','standard van', 79885, 'ford' FROM DUAL;
Note:
You had an extra . after the table name in the DDL statement and spaces in the mileage (18 325 and 79 885) which need removing and you needed an INTO keyword before the second insert.
It is also useful to name your constraints (then you can easily determine which constraint has been violated in later statements).
i want to insert values to oracle Object type by selecting values from other table
And the tables and insert statement looks like this.
CREATE TYPE Test_obj AS OBJECT (
attr1 VARCHAR2(20),
attr2 VARCHAR2(20),
attr3 VARCHAR2(25) );
/
CREATE TABLE resultrow_obj (
resultrow Test_obj ,
RESULTTABLEID NUMBER(20,0),
ROWNUMBER NUMBER(20,0) );
/
INSERT INTO resultrow_obj VALUES (
Test_obj (select col1,col2,col3 from Table2 where rownum<=1),
1,123 );
/
You've got it nearly right:
SQL> INSERT INTO resultrow_obj
2 VALUES((SELECT Test_obj('A', 'B', 'C')
3 FROM dual WHERE rownum <= 1),
4 1, 123);
1 row inserted
I have this table below in the picture that i want to create as an object-oriented table. I dont want the usual create table with relationships.... I just want to learn how to turn this table into an object-oriented table. Below is a picture of my tables and how are they connected:
CREATE TYPE A_TYPE AS OBJECT(
id INT,
col1 INT
);
/
CREATE TYPE A_REF_TABLE_TYPE AS TABLE OF REF A_TYPE;
/
CREATE TYPE B_TYPE AS OBJECT(
id INT,
col1 INT
);
/
CREATE TYPE B_REF_TABLE_TYPE AS TABLE OF REF B_TYPE;
/
CREATE TYPE C_TYPE AS OBJECT(
id INT,
a_list A_REF_TABLE_TYPE,
b_list B_REF_TABLE_TYPE,
col1 INT
);
/
CREATE TABLE A_TAB OF A_TYPE(
ID PRIMARY KEY
);
CREATE TABLE B_TAB OF B_TYPE(
ID PRIMARY KEY
);
CREATE TABLE C_TAB OF C_TYPE(
ID PRIMARY KEY
)
NESTED TABLE a_list STORE AS c_a_lists
NESTED TABLE b_list STORE AS c_b_lists;
INSERT INTO A_TAB VALUES( A_TYPE( 1, 3 ) );
INSERT INTO A_TAB VALUES( 2, 4 );
INSERT INTO B_TAB VALUES ( B_TYPE( 1, 7 ) );
INSERT INTO B_TAB VALUES ( 2, 2 );
INSERT INTO B_TAB VALUES ( 3, 10 );
INSERT INTO C_TAB VALUES (
1,
A_REF_TABLE_TYPE(
( SELECT REF(a) FROM A_TAB a WHERE ID = 2 ) -- Single value
),
( -- Multiple values
SELECT CAST( COLLECT( REF(b) ) AS B_REF_TABLE_TYPE )
FROM TAB_B b
WHERE ID IN ( 1, 3 )
),
42
);
INSERT INTO C_TAB VALUES (
2,
NULL, -- Unknown
B_REF_TABLE_TYPE(), -- No values
54
);
Output:
SELECT * FROM C_TAB;
ID A_LIST B_LIST COL1
-- ------------------------------- --------------------------------------------- ----
1 A_REF_TABLE_TYPE( A_TYPE(2,4) ) B_REF_TABLE_TYPE( B_TYPE(1,7), B_TYPE(3,10) ) 42
2 (null) B_REF_TABLE_TYPE() 54