Oracle - How to get a number from an object in a sql query? - sql

I have this object:
CREATE TYPE CarType AS OBJECT(
price_id NUMBER,
quantity NUMBER.
MAP MEMBER FUNCTION get_price_id RETURN NUMBER
);
and this table:
CREATE TABLE Cars(
carid NUMBER PRIMARY KEY,
carinfo cartype,
CONSTRAINT car_fk FOREIGN KEY(carinfo.price_id) REFERENCES prices(price_id)
);
and I want to get the carid,price_id from Cars table with a sql query.

You must remember about aliasing your table and accessing columns with object type using alias, otherwise you will get ORA-00904 invalid identifier error.
This query will work:
SELECT C.CARID, C.CARINFO.PRICE_ID, C.CARINFO.QUANTITY FROM CARS C;
But this will not:
SELECT CARS.CARID, CARS.CARINFO.PRICE_ID, CARS.CARINFO.QUANTITY FROM CARS;

Related

Can I change an attribute name from a table derived from a type?

Folowing the Object-Relational Database model, I wanted to create the tables or_doctor and or_recepcionist derived from the type t_employee.
Here, follows the type structure:
DROP TYPE t_employee FORCE;
CREATE OR REPLACE TYPE t_employee AS OBJECT (
num_employee INTEGER,
name_employee VARCHAR2(50),
birthdate_employee DATE
);
And here, the tables' structure:
DROP TABLE or_doctor CASCADE CONSTRAINTS;
CREATE TABLE or_doctor OF t_employee (
PRIMARY KEY (num_employee),
name_employee NOT NULL,
birthdate_employee NOT NULL
) OBJECT IDENTIFIER IS SYSTEM GENERATED;
DROP TABLE or_recepcionist CASCADE CONSTRAINTS;
CREATE TABLE or_recepcionist OF t_employee (
PRIMARY KEY (num_employee),
name_employee NOT NULL,
birthdate_employee NOT NULL
) OBJECT IDENTIFIER IS SYSTEM GENERATED;
Doing so, the attributes names, on both tables, will end up with "employee". Could I change the attribute name so they are specific in each table at the moment I'm creating the table?
E.G.:
Table or_doctor: num_doct, name_doct, birthdate_doct.
Table or_recepcionist: num_recep, name_recep, birthdate_recep.
As a frame challenge, don't add a suffix to your identifiers then you don't need to worry about the suffix being incorrect:
CREATE TYPE t_employee AS OBJECT (
num INTEGER,
name VARCHAR2(50),
birthdate DATE
);
CREATE TABLE or_doctor OF t_employee (
PRIMARY KEY (num),
name NOT NULL,
birthdate NOT NULL
) OBJECT IDENTIFIER IS SYSTEM GENERATED;
CREATE TABLE or_receptionist OF t_employee (
PRIMARY KEY (num),
name NOT NULL,
birthdate NOT NULL
) OBJECT IDENTIFIER IS SYSTEM GENERATED;
If you try to rename the column:
ALTER TABLE or_doctor RENAME COLUMN name TO name_doctor;
Then you will get the error:
ORA-23291: Only base table columns may be renamed
If you are using object-derived tables then you appear to be stuck with the identifiers from the object; so, make the object names generic so that they are appropriate in every place they are going to be used.

How cast few atributes from relational table into varray on creating view

I need to create VIEW with VARRAY casted from 3 atributes in relational table.
I tried many ways, but I didn't get a positive result.
Also can't find a solution in the oracle documentation.
CREATE TABLE Client (
ID_Client NUMBER(7,0),
Phone1 VARCHAR2(9),
Phone2 VARCHAR2(9),
Phone3 VARCHAR2(9),
CONSTRAINT Client_PK
PRIMARY KEY (ID_Client)
);
/
CREATE TYPE phone_vartyp IS VARRAY(3) OF VARCHAR2(9);
/
CREATE TYPE client_objtyp AS OBJECT (
ID_Client NUMBER(7,0),
Phones phone_vartyp
);
/
CREATE VIEW client_objv OF client_objtyp
WITH OBJECT IDENTIFIER (ID_Client)
AS SELECT c.ID_Client,
CAST(MULTISET(SELECT c.Phone1, c.Phone2, c.Phone3
FROM Client c) AS phone_vartyp)
FROM Client c; -- ORA-00932
/
CREATE VIEW client_objv OF client_objtyp
WITH OBJECT IDENTIFIER (ID_Client)
AS SELECT c.ID_Client,
(SELECT CAST(c.Phone1, c.Phone2, c.Phone3) AS phone_vartyp FROM Client c) as phone_vartyp
FROM Client c; -- ORA-00905
/
DROP TABLE Client;
DROP TYPE client_objtyp;
DROP TYPE phone_vartyp;
It seems you're overthinking this one. There's no need to use CAST or MULTISET or a subquery. The easiest way to create a VARRAY from a number of values is just to use the type as if it were a function and pass all of the elements as arguments.
The following appears to work:
CREATE OR REPLACE VIEW client_objv OF client_objtyp
WITH OBJECT IDENTIFIER (ID_Client)
AS SELECT c.ID_Client,
phone_vartyp(c.Phone1, c.Phone2, c.Phone3)
FROM Client c;

How to CREATE TABLE with disjoint relationship in SQL

I am trying to create a table using a disjoint subtype relationship.
For example, if the Supertype is furniture, and I have 3 Subtypes of furniture: chair, couch, and table.
Then:
CREATE TABLE Furniture
(order_num NUMBER(15), desc VARCHAR2(20), type VARCHAR2(10));
How do I make an option to pick type of chair, couch or table?
You can use REFERENCES in the CREATE TABLE.
CREATE TABLE Furniture_SubTypes
(
sub_type VARCHAR(10) PRIMARY KEY
);
INSERT INTO Furniture_SubTypes VALUES ('Chair');
INSERT INTO Furniture_SubTypes VALUES ('Couch');
INSERT INTO Furniture_SubTypes VALUES ('Table');
CREATE TABLE Furniture
(
order_num NUMBER,
description VARCHAR(20),
sub_type REFERENCES Furniture_SubTypes(sub_type)
);
Use a check constraint:
CREATE TABLE Furniture (
order_num NUMBER(15),
description VARCHAR2(20),
type VARCHAR2(10),
check (type in ('chair', 'couch', 'table'))
);
Note that desc is a poor choice for a column name, because it is a keyword in SQL (used for order by).

Create a table of two types in PostgreSQL

I have created two types:
Create Type info_typ_1 AS (
Prod_id integer,
category integer);
Create Type movie_typ AS(
title varchar(50),
actor varchar(50),
price float);
And I want to create a table that consists of these two types. I know that for a table that consists of one type, it's:
CREATE TABLE Table1 of type1
(
primary key(prod_id)
);
Is there any way to do that for the two types I created above?
What I tried doing(which is wrong), is creating a third type that contains the first two:
Create Type info_ AS (
info info_typ_1,
movie movie_typ);
and then creating the table:
CREATE TABLE table1 of info_
(
primary key(Prod_id)
);
But it doesn't work. I get this error:
ERROR: column "prod_id" named in key does not exist
LINE 3: primary key(Prod_id)
^
********** Error **********
ERROR: column "prod_id" named in key does not exist
SQL state: 42703
Character: 43
You cannot make prod_id the primary key of table1 because the only columns are the two composite types info and movie. You cannot access the base types of these composite types in a PRIMARY KEY clause.
What you were trying to do works with a pk constraint on info or movie.
Except, it's probably not what you were looking for, which is not possible this way.
You could implement something like this with ...
Inheritance
Here you can inherit from multiple parent tables (substitute for your types). Example:
CREATE TABLE info (
prod_id integer
,category integer
);
CREATE TABLE movie (
title text
,actor text
,price float
);
CREATE TABLE movie_info (
PRIMARY KEY(prod_id) -- now we can use the base column!
)
INHERITS (info, movie);
INSERT INTO movie_info (prod_id, category, title, actor, price)
VALUES (1, 2, 'who donnit?', 'James Dean', '15.90');
SELECT * FROM movie_info;
-> SQLfiddle demonstrating both.
Be sure to read about limitations of inheritance in the manual.

error: ORA-01730: invalid number of column names specified

Please help. I want to create an object view from the ffl tables but i keep getting the above error and can't find any solution.
create table COPY_BOOK (
NUM number(4,0),
DATE_Purchase date,
PRICE number(5,2),
LOAN_code varchar2(20) ,
STATUS varchar2(15) check (STATUS in ('GOOD','DAMAGED')),
CONSTRAINT CP_PK primary key (num) ,
constraint Loan_code_D check (LOAN_CODE in ('NO', 'LOAN'))
);
create or replace type copy_book_t as object(
num number(4, 0),
loan_code varchar2 (20)
);
/
create or replace view Vcopy_book of copy_book_t
with object oid (num)
as select cb.num, cb.date_purchase, cb.price, cb.loan_code, cb.status
from copy_book cb;
/
Is there a problem with the type definition?
From the documentation:
The procedure for defining an object view is:
Define an object type, where each attribute of the type corresponds to an existing column in a relational table.
Write a query that specifies how to extract the data from the relational table. Specify the columns in the same order as the
attributes in the object type.
You have created your object type with two attributes, but you're trying to populate it with five columns from your relational table.
You either need to change your object type to have the same five attributes (demo), or only select the num and loan_code columns in the view (demo).
Incidentally, the documentation also recommends using with object identifier rather than with object oid.