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.
Related
CREATE type recommendation as object(
descriptions varchar2(200)
);
create type recomand as table of recommendation;
create type traitement_type as object (
id_traitement number(7),
duree varchar2(25),
recome recomand,
description varchar2(250)
);
CREATE TABLE Traitement (primary key(id_traitement))
nested table recome store as Les_recommendations;
i execute these commands and at the last query i got the error :
ORA-00904: : invalid identifier
any solutions ?
Your create table statement doesn't include a column list. It's interpreting "primary key" a column and spaces are not allowed. Look up the proper format for create table statements and PK constraints.
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.
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;
I'm designing an object-relational model database. I have a supertype named "topico_t" and 4 subtypes of this supertype named "anotacao_t", "tarefa_t", "memo_t" and "contacto_t". See here the DDL snippet:
CREATE OR REPLACE TYPE categoria_t AS OBJECT(
nome VARCHAR2(25),
pai REF categoria_t
);
CREATE OR REPLACE TYPE categoria_tab_t AS TABLE OF REF categoria_t;
CREATE OR REPLACE TYPE topico_t AS OBJECT(
titulo VARCHAR2(100),
ultimaAlteracao DATE,
categorias categoria_tab_t
--referencias topico_tab_t
) NOT FINAL;
CREATE OR REPLACE TYPE topico_tab_t AS TABLE OF REF topico_t;
ALTER TYPE topico_t ADD ATTRIBUTE referencias topico_tab_t CASCADE;
CREATE OR REPLACE TYPE periodo_t AS OBJECT(
inicio DATE,
fim DATE
);
CREATE OR REPLACE TYPE repeticao_t AS OBJECT(
frequencia VARCHAR2(10),
duracao periodo_t
);
CREATE OR REPLACE TYPE anotacao_t UNDER topico_t(
periodo periodo_t,
repeticao repeticao_t
);
CREATE OR REPLACE TYPE telefone_t AS OBJECT(
numero VARCHAR2(25)
);
CREATE OR REPLACE TYPE telefone_tab_t AS TABLE OF telefone_t;
CREATE OR REPLACE TYPE morada_t AS OBJECT(
rua VARCHAR2(100),
localidade VARCHAR2(50),
codigoPostal VARCHAR2(10)
);
CREATE OR REPLACE TYPE morada_tab_t AS TABLE OF morada_t;
CREATE OR REPLACE TYPE contacto_t UNDER topico_t(
telefones telefone_tab_t,
moradas morada_tab_t,
email VARCHAR2(100),
url VARCHAR2(150)
);
CREATE OR REPLACE TYPE tarefa_t UNDER topico_t(
dataFim DATE,
completo NUMBER(1,0),
conteudo VARCHAR2(255)
);
CREATE OR REPLACE TYPE memo_t UNDER topico_t(
conteudo VARCHAR2(255)
);
CREATE TABLE categorias OF categoria_t;
CREATE TABLE topicos OF topico_t
NESTED TABLE categorias STORE AS categorias_nested
NESTED TABLE referencias STORE AS referencias_nested;
So, then I populate this table "topicos" with this:
INSERT INTO topicos VALUES (tarefa_t(
'Dissertacao',
TO_DATE('2018/02/13', 'YYYY/MM/DD'),
categoria_tab_t((select ref(c) from categorias c where nome='FEUP')),
topico_tab_t((select ref(t) from topicos t where titulo='Diogo Pereira'), -- which is an object of the subtype "contacto_t"
(select ref(t) from topicos t where titulo='Comecar a dissertacao'), -- which is an object of the subtype "memo_t"
(select ref(t) from topicos t where titulo='Apresentar Dissertacao'), -- which is an object of the subtype "tarefa_t"
(select ref(t) from topicos t where titulo='Reuniao com Orientador da Dissertacao')), -- which is an object of the subtype "anotacao_t"
TO_DATE('2018/08/13', 'YYYY/MM/DD'),
0,
'Dissertacao all over again'));
So, I have to build a query or even a PL/SQL block that returns me all the rows of the table "topicos" that contains at least, in the nested table "referencias", one instance object for each of this 4 subtypes mentioned above. Ideally this query would return me that row (mentioned in the above INSERT).
Best regards and hope you're having a good Worker's Day! ;)
You have a mistake in your DDL code. You are creating a base type topico_t and then some subtypes under that type, but you're creating a single table of base type objects only. The problem with this is that you're expecting that table to hold objects of any subtype, which will not be the case due to what is known as object slicing. The table you've created has only the columns which correspond to the fields you've defined for the base type.
Therefore, you need to create tables for all of the subtypes which you will eventually instantiate. You should only create a table for the base type if it makes sense for that type to be instantiated, that is, if an object of the base type which doesn't belong to any of the subtypes could exist.
After doing this, the query you're trying to write should use the function TREAT. Note that, according to the documentation, this function returns NULL when the expression is not of the type you're trying to cast to, so the query you need to write should be as simple as testing if there is at least one row with a non-null result field when selecting from the nested table and attempting to cast to each of the subtypes you've created. Check the example on the documentation to see how to use this function.
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.