Working out the Oracle Select Statement - oracle

what im trying to do is to find number of saving account at each branch, and display the number and branch address.
here is code :
create type address as object
(
street varchar2(20),
city varchar2(10),
p_code varchar2(8)
);
create type Branch as object
(
BId varchar2(3),--branch id
brAddress address,
bPhone int
);
create table tb_Branch of Branch
(
bid primary key
);
create type account as object
(
accNum varchar2(4), --pk
accType varchar2(8), -- check(current, saving)
balance number(8,2)
BId_ref ref BId
);
create tb_account of account
(
accNum primary key,
constraint accType_const check(accType IN ('current','savings'))
);`
Please help!
thanks!

Maybe the following example (Oracle 12c) will help you to find a solution ... (the TYPEs and TABLEs may need tweaking).
Types and tables
-- types
create type address_t as object (
street varchar2(20)
, city varchar2(10)
, postcode varchar2(8)
)
/
create type branch_t as object (
brid varchar2(64)
, braddress address_t
, brphone varchar2(24)
)
/
create type account_t as object (
accnum varchar2(4)
, acctype varchar2(8)
, balance number(12,2)
)
/
-- tables
create table branches (
branch branch_t
, constraint branch_pk primary key ( branch.brid )
);
create table accounts (
id number generated always as identity primary key
, account_details account_t
, constraint acc_type_check check(
account_details.acctype in ('current','savings')
)
, branchid references branches( branch.brid )
);
Some INSERTs (table BRANCHES)
insert into branches ( branch )
values (
branch_t( '66-20-67'
, address_t( '1 High St', 'Edinburgh', 'EH1 1AA' )
, '00441155700340' )
) ;
-- trying to insert this again
-- gives us
-- ORA-00001: unique constraint (...BRANCH_PK) violated -> PK constraint working
insert into branches ( branch )
values (
branch_t( '88-45-13'
, address_t( '2 Princes St', 'Edinburgh', 'EH2 2BB' )
, '00441156800900' )
) ;
-- The BRANCHES table contains:
SQL> select * from branches;
BRANCH(BRID, BRADDRESS(STREET, CITY, POSTCODE), BRPHONE)
---------------------------------------------------------------------------------------------------------------------------
BRANCH_T('66-20-67', ADDRESS_T('1 High St', 'Edinburgh', 'EH1 1AA'), '00441155700340')
BRANCH_T('88-45-13', ADDRESS_T('2 Princes St', 'Edinburgh', 'EH2 2BB'), '00441156800900')
Populate the ACCOUNTS table
begin
insert into accounts ( account_details, branchid )
values ( account_t ( '7890', 'savings', 123456.78 ), '66-20-67' ) ;
insert into accounts ( account_details, branchid )
values ( account_t ( '7891', 'savings', 222222.22 ), '66-20-67' ) ;
insert into accounts ( account_details, branchid )
values ( account_t ( '7892', 'savings', 333333.33 ), '88-45-13' ) ;
insert into accounts ( account_details, branchid )
values ( account_t ( '6789', 'current', 234567.89 ), '88-45-13' ) ;
end;
/
-- fails due to CHECK constraint
insert into accounts ( account_details, branchid )
values ( account_t ( '1234', 'standard', 4567.89 ), '66-20-67' ) ;
-- ORA-02290: check constraint (...ACC_TYPE_CHECK) violated
Query
/*
from your question:
" what im trying to do is
to find number of saving account at each branch,
and display the number and branch address "
*/
-- suggested query
select
A.account_details.acctype as acctype
, B.branch.brid as branchid
, B.branch.braddress.city as city
, count( * )
from branches B
join accounts A on B.branch.brid = A.branchid
where A.account_details.acctype = 'savings'
group by A.account_details.acctype
, B.branch.brid
, B.branch.braddress.city ;
ACCTYPE BRANCHID CITY COUNT(*)
-------- ---------- ---------- ----------
savings 88-45-13 Edinburgh 1
savings 66-20-67 Edinburgh 2

Related

Foreign key keeps saying not enough values

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?

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.

Oracle View Object Type Column

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

LINQ Left Join on Max Date

Ok so here are my tables in the database:
CREATE DATABASE Temp
GO --------------------------
USE Temp
GO --------------------------
CREATE TABLE Table1
(
Table1Id INT IDENTITY(1, 1) ,
Name VARCHAR(20) ,
CONSTRAINT pk_Table1 PRIMARY KEY ( Table1Id )
)
GO --------------------------
CREATE TABLE Table2
(
Table2Id INT IDENTITY(1, 1) ,
Table1Id INT ,
NAME VARCHAR(20) ,
TheDate SMALLDATETIME ,
CONSTRAINT pk_Table2 PRIMARY KEY ( Table2Id ) ,
CONSTRAINT fk_Table2_Table1 FOREIGN KEY ( Table1Id ) REFERENCES Table1 ( Table1Id )
)
GO --------------------------
INSERT INTO Table1
( Name )
VALUES ( 'Stack Overflow' )
GO --------------------------
INSERT INTO Table1
( Name )
VALUES ( 'Expert Sex Change' )
GO --------------------------
INSERT INTO Table1
( Name )
VALUES ( 'Code Project' )
GO --------------------------
INSERT INTO dbo.Table2
( Table1Id ,
NAME ,
TheDate
)
VALUES ( 1 ,
'S1' ,
'11-01-2012'
)
GO --------------------------
INSERT INTO dbo.Table2
( Table1Id ,
NAME ,
TheDate
)
VALUES ( 1 ,
'S2' ,
'11-01-2013'
)
GO --------------------------
INSERT INTO dbo.Table2
( Table1Id ,
NAME ,
TheDate
)
VALUES ( 2 ,
'E1' ,
'10-01-2013'
)
And here's my LINQ:
from t1 in Table1s
join t2 in Table2s.OrderByDescending(x => x.TheDate)
on t1.Table1Id equals t2.Table1Id into tt
from t2 in tt.DefaultIfEmpty()
select new
{
t1.Table1Id,
t1.Name,
t2.NAME,
t2.TheDate
}
This one returns:
Table1Id - Name - NAME - TheDate
1 - Stack Overflow - S2 - 11/1/2013
2 - Expert Sex Change - E1 - 10/1/2013
1 - Stack Overflow - S1 - 11/1/2012
3 - Code Project - null - null
I want the LINQ query not to return the third line, as is from an older Date Value.
I think I got it, the answer is:
from t1 in Table1s
join t2 in Table2s
on t1.Table1Id equals t2.Table1Id
into tt
from x in tt.DefaultIfEmpty()
// where ... t1 && x ..
orderby t1.Table1Id
group x by new {t1.Table1Id,t1.Name} into g
select new {
Table1Id = g.Key.Table1Id,
Name = g.Key.Name,
TheDate = g.Max(c => c.TheDate)
}

How do i turn this tables into an object-oriented table (object-relation) in Oracle

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

Resources