How to create Oracle object type with collection as attrubuteobject type with collection as attrubute - oracle

In oracle database I have created type
CREATE OR REPLACE TYPE DOSSIER_RESULT AS OBJECT
(
id number,
user_id number
)
Then I created the collection of this type
CREATE OR REPLACE TYPE DOSSIER_RESULTS_ARRAY AS TABLE OF DOSSIER_RESULT
Then I added one more attribute in first type definition like this
CREATE OR REPLACE TYPE DOSSIER_RESULT AS OBJECT
(
id number,
user_id number,
child DOSSIER_RESULTS_ARRAY
)
But it compiled with error
Error: PLS-00201: identifier 'DOSSIER_RESULTS_ARRAY' must be declared
The question is: How can I create an Object type with collection of objects of this type in it?

Related

Accessing table from an object

Is it possible to access an existing table from an object?
Here the simplified snippet:
CREATE OR REPLACE TYPE MYOBJ AS OBJECT(
MEMBER PROCEDURE MYEXPORT( ERRORS.ERRORS_ID%TYPE));
ERRORS is a table. When I write it like above I'm getting error:
PLS-00201 - identifier must be declared.
Any clue? Thanks!
You have three issues:
The syntax is
MEMBER PROCEDURE procedure_name (argument_name data_type)
You have specified the data type but not an argument name which is why you get the error message PLS-00201 - identifier must be declared. as you need to specify an identifier for the argument.
table_name.column_name%TYPE declarations can be used in the PL/SQL scope but not in the SQL scope. Your object declaration is in the SQL scope so you need to fully define the data type rather than referring to a column.
An object must have at least one attribute.
You want:
CREATE OR REPLACE TYPE MYOBJ AS OBJECT(
attr1 NUMBER,
MEMBER PROCEDURE MYEXPORT( v_errors_id NUMBER )
);

Unable to create a table with a column of object type (and the same object type contains an attribute of nested table type)

I am trying to create a table with a column of object type and tricky nested table hierarchy. Getting ORA-22913 error. In CREATE table statement the column "theCol" is of type object (i.e. MainObj). MainObj contains an attribute of type nested table i.e. ChildTab.
I think am supposed to use NESTED TABLE clause in CREATE TABLE statement. But not sure how to use it here because "theCol" is NOT of nested table type.
DROP TYPE MainObj;
DROP TYPE ChildTab;
DROP TYPE ChildObj;
CREATE TYPE ChildObj AS OBJECT (
naame varchar2(20)
, kaam varchar2(20)
);
/
CREATE TYPE ChildTab AS TABLE OF ChildObj;
/
Create TYPE MainObj as OBJECT (
KEEY VARCHAR2(5),
ChildList ChildTab
);
/
CREATE TABLE TestTableDesi (
theCol MainObj
);
/
Type dropped.
Type dropped.
Type dropped.
Type created.
Type created.
Type created.
ORA-22913: must specify table name for nested table column or attribute
Just found the solution here. How do I create an Oracle table of objects containing nested tables?
The create table statement should be as follows.
CREATE TABLE TestTableDesi (
theCol MainObj
) nested table theCol.ChildList store as ChildList_tab ;
/

SQL3 ORA-22913: must specify table name for nested table column or attribute

I am trying to define a table in SQL3 of a type that contains a nested table in its type declaration. I do not understand why I am always getting the same error despite having tried several solutions. Here is the piece of code:
create type Composite;
/
create type L_PieceComposite as table of ref Composite;
/
create type Piece as object(
name VARCHAR(20),
containedInto L_PieceComposite
)
not final not instantiable;
/
create type PieceQuantity as Object (
quantity NUMBER,
pieceref ref Piece
);
/
create type L_PieceQuantity as table of PieceQuantity;
/
create type Composite UNDER Piece(
cost NUMBER,
contains L_PieceQuantity
);
/
In another file I use:
create table thePieces of Piece;
CREATE TABLE theComposites of Composite NESTED TABLE contains store as tab7;
But get the following error:
ORA-22913: must specify table name for nested table column or attribute
Could anyone help?
Thanks
SOLVED..conclusion: we must beware of inherited tables.
create table lesComposites of Composite nested table containedInto store as tab5 nested table contains store as tab6;

Create object type with rowid attributes

I am trying to create a type with the rowid data type, but I am getting this error because of the type I am trying to use:
SQL> CREATE TYPE join_t IS OBJECT (inn rowid, out rowid );
/
Warning: Type created with compilation errors.
Even though I can create a table with rowid data type:
SQL> create table test_rowid (inn rowid,out rowid);
Table created.
Is it possible to create this type join_t above, with rowid-type attributes?
No, you can't create an object type with rowid fields. If you looks at the actual error raised, via the user_errors view or with the SQL*Plus command show errors, you will see:
LINE/COL ERROR
-------- ------------------------------------------------------------------------------
1/28 PLS-00530: Illegal type used for object type attribute: 'ROWID'.
1/39 PLS-00530: Illegal type used for object type attribute: 'ROWID'.
The documenation says:
Restrictions on datatype
You cannot impose the NOT NULL constraint on an attribute.
You cannot specify attributes of type ROWID, LONG, or LONG RAW.
You cannot specify a data type of UROWID for an ADT.
...
As a workaround, you could potentially use a string type in your object, and convert the values when setting to getting the field values, via the rowidtochar and chartorowid functions:
CREATE TYPE join_t IS OBJECT (inn varchar2(18), out varchar2(18) );
/
Type JOIN_T compiled
SELECT join_t(rowidtochar(rowid), rowidtochar(rowid)) FROM DUAL;
JOIN_T(ROWIDTOCHAR(ROWID),ROWIDTOCHAR(ROWID))(INN, OUT)
-------------------------------------------------------
JOIN_T('AAAAB0AABAAAAOhAAA', 'AAAAB0AABAAAAOhAAA')
Storing rowids in an object doesn't seem particularly useful though, as they can change.

Error in creating nested table involving inheritence

I have a somewhat complex structure as follows :
create or replace type user_typ as object(
user_id number(19,0),
username nvarchar2(40 char)
);
I inherit an applicant_typ from this :
create or replace type applicant_typ under user_typ (
resume_text nclob
);
My design involves jobs to which applicants can apply. To this end, I create an application_typ as follows :
create or replace TYPE Application_typ AS OBJECT (
application_id NUMBER,
candidate applicant_typ,
time_of_app DATE
);
CREATE TYPE Application_tab IS TABLE OF Application_typ;
And now I want to create an object type called Job_typ, and a table containing those objects, wherein there will be a nested table for applications :
CREATE OR REPLACE TYPE Job_typ AS OBJECT (
job_ID NUMBER,
company_ID NUMBER,
description NVARCHAR2(1000),
name NVARCHAR2(200),
application Application_tab,
MAP MEMBER FUNCTION job_no RETURN NUMBER,
MEMBER PROCEDURE no_of_applicants
);
All of this works fine. The issue is when I try to create a table of type Job_typ :
CREATE TABLE Job_tab OF Job_typ
NESTED TABLE application STORE AS application_nt;
This doesn't work, giving the error :
SQL Error: ORA-02320: failure in creating storage table for nested table column APPLICATION
ORA-22913: must specify table name for nested table column or attribute
02320. 00000 - "failure in creating storage table for nested table column %s"
*Cause: An error occurred while creating the storage table for the
specified nested table column.
What am I doing wrong?
EDIT : I tried some different things. If I change application_typ as follows :
CREATE OR REPLACE TYPE Application_typ AS OBJECT (
application_id NUMBER,
candidate User_Typ, -- NOTE: This attribute is now of type User_typ instead of the inherited type
time_of_app DATE,
);
CREATE TYPE Application_tab IS TABLE OF Application_typ;
Then everything else works, and I am able to create the Job table. Why do I get the error on using the inherited type?
I tried the following in Oracle 11.2.0.1 and didn't get any error. I made a slight change though:
CREATE OR REPLACE TYPE user_typ AS OBJECT
(
user_id NUMBER (19, 0),
username NVARCHAR2 (40 CHAR)
) NOT FINAL; -- << Notice the NOT FINAL keyword
create or replace type applicant_typ under user_typ (
resume_text nclob
);
CREATE OR REPLACE TYPE Application_typ AS OBJECT
(
application_id NUMBER,
candidate applicant_typ,
time_of_app DATE
);
CREATE TYPE Application_tab IS TABLE OF Application_typ;
CREATE OR REPLACE TYPE Job_typ AS OBJECT
(
job_ID NUMBER,
company_ID NUMBER,
description NVARCHAR2 (1000),
name NVARCHAR2 (200),
application Application_tab,
MAP MEMBER FUNCTION job_no
RETURN NUMBER,
MEMBER PROCEDURE no_of_applicants
);
CREATE TABLE Job_tab OF Job_typ
NESTED TABLE application
STORE AS application_nt;
While trying to create all your types and keywords, I got the error:
[Error] PLS-00590 (10.1): PLS-00590: attempting to create a subtype UNDER a FINAL type
This is because Oracle doesn't allow creation of a subtype on a FINAL type. If you don't define any finalizing clause for the base type, the default is FINAL.
Read more on Oracle Docs.
If you are coding for the real world (read industry), I'd advise against using nested tables as column types. You end up spending your entire life trying to nest and un-nest these. I'd suggest you normalize your schema as much as you can or need and leave nested tables for operations in PL/SQL code blocks.

Resources