Inconsistent datatypes : CAST REF? - sql

I've this schema:
CREATE OR REPLACE TYPE tree_t
/
CREATE OR REPLACE TYPE element_t AS OBJECT (
libelle varchar2(100),
parent REF tree_t,
) NOT FINAL NOT INSTANTIABLE
/
CREATE OR REPLACE TYPE tree_t UNDER element_t()
/
CREATE OR REPLACE TYPE leaf_t UNDER element_t()
/
And I'm trying to insert in this table:
CREATE TABLE elements OF element_t;
For an element_t without parent, no problem :
INSERT INTO elements VALUES (tree_t('first', NULL));
But with a parent :
INSERT INTO elements
VALUES (tree_t('second',
(SELECT REF(e)
FROM elements e
WHERE e.libelle = 'first')));
I've this result:
ORA-00932: inconsistent datatypes: expected REF CINETREE.TREE_T
got REF CINETREE.ELEMENT_T
Can I keep this schema, and how to make insertions?
(with CAST?)

TREAT should do the trick:
INSERT INTO elements
VALUES (tree_t('second',
(SELECT TREAT(REF(e) AS REF tree_t)
FROM elements e
WHERE e.libelle = 'first')));

Related

Oracle SQL3 3 nesting tables insert problem

I'm making an SQL3 script where I create types and then create tables and nested tables.
The prolem I'm getting happens when I want to insert a row where it says :
ORA-00932: inconsistent datatypes: expected UDT got CHAR
this is an online reproduction of the problem where the types and tables are already created, you can try to insert:
https://www.tutorialspoint.com/oracle_terminal_online.php?fbclid=IwAR0GgaLe2_GvGsEb80eB-D0uKDSDJDr1WNBPiK3mHQqpJQrtfacQ1cf03NA
the following is the types creation script
CREATE TYPE T_Personne ;
/
CREATE TYPE T_SET_Tag AS TABLE OF Varchar2(30);
/
CREATE TYPE T_Message AS OBJECT (
Texte Varchar2(500),
DateEcrit Date,
Tags T_SET_Tag
);
/
CREATE TYPE T_SET_Message AS TABLE OF T_Message;
/
CREATE TYPE T_Contact AS OBJECT(
Per REF T_Personne,
Depuis Date
);
/
CREATE TYPE T_SET_Contact AS TABLE OF T_Contact;
/
CREATE OR REPLACE TYPE T_Personne AS OBJECT (
Prenom Varchar2(30),
Suit T_SET_Contact,
Ecrit T_SET_Message
);
/
this one is the table creation script
CREATE TABLE TAB_Personne OF T_Personne
NESTED TABLE Suit STORE AS TAB_suit,
NESTED TABLE Ecrit STORE AS TAB_ecrit(
NESTED TABLE Tags STORE AS TAB_Tags
);
and finally the script I'm using to insert my new rows
INSERT INTO TAB_Personne VALUES(
'Baam',
T_SET_Contact(),
T_SET_Message()
);
INSERT INTO TAB_Personne VALUES(
'Rachel',
T_SET_Contact(
(SELECT REF(P)
FROM TAB_Personne P
WHERE P.Prenom='Baam'),
to_date('01/01/2018', 'dd/mm/yyyy')
),
T_SET_Message(
'Paris candidat aux jeux Olympiques 2022',
to_date('01/06/2019', 'dd/mm/yyyy'),
T_SET_Tag('JM2022')
)
);
the error message I'm getting is
1 row created.
'Paris candidat aux jeux Olympiques 2022', *
ERROR at line 10:
ORA-00932: inconsistent datatypes: expected UDT got CHAR
I'd be glad if anyone can guide me through this, thanks.
You are specifying a T_SET_Message collection but you then need T_Message objects within that; you're supplying the attributes of that object type, not an actual object of the type. The first element in the (non-)collection is a string, hence the error you get - you've supplied a string ('Paris...') when it's expecting to see a UDT (T_Message('Paris...', ...)).
You are also doing the same thing with the T_SET_Contact collection.
You need to wrap your current attributes in object constructors; so this works:
INSERT INTO TAB_Personne VALUES(
'Rachel',
T_SET_Contact(
T_Contact(
(SELECT REF(P)
FROM TAB_Personne P
WHERE P.Prenom='Baam'),
to_date('01/01/2018', 'dd/mm/yyyy')
)
),
T_SET_Message(
T_Message(
'Paris candidat aux jeux Olympiques 2022',
to_date('01/06/2019', 'dd/mm/yyyy'),
T_SET_Tag('JM2022')
)
)
);
db<>fiddle

REF() function returns "SQL command not properly ended"

I'm trying to familiarize myself with a O/R db, which has led me to try to get object references.
Started out by listing all_objects for a specific user, and just picked one object (CF02) whose type is TABLE i.e. OBJECT_TYPE = 'TABLE'
I then opened the table, and just went with one of the rows whose first field (OBJECT_ID) is 9142055040413031761.
Then I tried to get the ref() on that row.
SELECT ref(cf) FROM rdbmgr.CF02 as cf
WHERE OBJECT_ID = 9142055040413031761
Hoping to get a similar result to that in the Oracle books, which is an internalnumber for the location of the object...
you can use a ref() function if your table was created from object type.
REF takes as its argument a correlation variable (table alias) associated with a row of an object table or an object view.
e.g. you have an object type:
create or replace TYPE t_pos AS OBJECT
(
x number,
y number
)
/
you can create a table
CREATE TABLE position OF t_pos ;
-- insert some data for test
insert into position values (1,2);
so you have a table position
now you can so a select with a ref function
select ref(t) from position t;
Result:
REF(E)
--------------------------------------------------------------------------------
0000280209587CADBD96F74009BBF01C1596D74E72E7986EC7F3AF40B4A264DA1BE6FE27D30040B2
790000
if you table was created as create table position(x number, y number)
you can't use ref function in your select
Have a look at documentation here

Circular Dependency -Table Insertion Error

I want to insert data into table but got below error..Can any one help me..
CREATE OR REPLACE TYPE TEST_TYP FORCE IS OBJECT
("id" VARCHAR(5000 NULL)
NOT FINAL;
CREATE OR REPLACE TYPE TEST_TAB is table of REF TEST_TYP;
CREATE OR REPLACE TYPE TEST1_TYP FORCE IS OBJECT
("id" VARCHAR2(500) NULL,
"extension" "TEST_TAB" NULL )
NOT FINAL;
CREATE TABLE "TEST_OBJ_TABLE" OF "TEST1_TYP"
NESTED TABLE "extension" STORE AS "Allin"
When I try to insert using this statementL
insert into "TEST_OBJ_TABLE" ("id","extension")
VALUES(
'0FE71A85',
"TEST_TAB"("TEST_TYP"( '0FE71A8'))
);
It throws this error
Error at Command Line : 59 Column : 12
Error report -
SQL Error: ORA-00932: inconsistent datatypes: expected REF SUB_HWOW.TEST_TYP got SUB_HWOW.TEST_TYP
00932. 00000 - "inconsistent datatypes: expected %s got %s"
*Cause:
*Action:
You have to modify object TEST_TYP -> varchar2 has to be max 4000.
You have to store this object in db.
Create object table for TEST_TYP
create table t_for_test_type of TEST_TYP;
To obtain object reference, the object have to be save in db table. In your case:
declare
v_ref_to_test_type1 ref TEST_TYP;
begin
insert into t_for_test_type t values('abcd1') return ref(t) into v_ref_to_test_type1;
end:
Join all parts together.
declare
v_ref_to_test_type1 ref TEST_TYP;
v_ref_to_test_type2 ref TEST_TYP;
begin
insert into t_for_test_type t values('abcd1') return ref(t) into v_ref_to_test_type1;
insert into t_for_test_type t values('abcd2') return ref(t) into v_ref_to_test_type2;
insert into TEST_OBJ_TABLE values (TEST1_TYP('abcd',new TEST_TAB(v_ref_to_test_type1,v_ref_to_test_type2)));
end;
Query table.
select t."id",x.column_value from TEST_OBJ_TABLE t, table(t."extension") x it returns id + ref to other object
Viewing the referenced object.
select t."id",deref(x.column_value) from TEST_OBJ_TABLE t, table(t."extension") x
Note1. You should avoid declaring attribute using double quote. Db becomes case sensitive and it's not normal situation :)
Note2. I don't know why code formatting is not working today
Question. Why are you trying to use such complicated construction?
Changed the original answer. The quotes are doing you no favors - nor was calling your column names id. Removed the REF reference.
CREATE OR REPLACE TYPE TEST_TYP FORCE IS OBJECT
(id1 VARCHAR(4000) NULL)
NOT FINAL;
CREATE OR REPLACE TYPE TEST_TAB is table of TEST_TYP;
CREATE OR REPLACE TYPE TEST1_TYP FORCE IS OBJECT
(id2 VARCHAR2(500) NULL,
extension TEST_TAB NULL )
NOT FINAL;
CREATE TABLE TEST_OBJ_TABLE OF TEST1_TYP
NESTED TABLE extension STORE AS Allin ;
insert into TEST_OBJ_TABLE ( ID2, EXTENSION)
VALUES(
'0FE71A85',
TEST_TAB(TEST_TYP( '0FE71A8'))
);
SELECT * FROM TEST_OBJ_TABLE ;

How to return user-defined type as varchar2?

Let's consider a table with user defined type.
create or replace type reftype is object (id number, name varchar2(40), details varchar2(1000));
create table testref(c1 reftype);
insert into testref values (REFTYPE(4, 'asd', 'aaa'));
insert into testref values (REFTYPE(3, 'asf', 'baa'));
insert into testref values (REFTYPE(2, 'asg', 'aba'));
insert into testref values (REFTYPE(1, 'ash', 'aab'));
/
select * from testref;
Select returns column with objects of user type. When I execute it in SQL*plus I will see:
SQL> select * from testref
REFTYPE(4, 'asd', 'aaa')
REFTYPE(3, 'asf', 'baa')
REFTYPE(2, 'asg', 'aba')
REFTYPE(1, 'ash', 'aab')
How can I write my query to return such output as a text (let's say varchar2).
SQL> select substr(c1,1,4) from testref;
select substr(c1,1,4) from testref
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected CHAR got KACPER.REFTYPE
The same with:
select substr(cast(c1 as varchar2(1000)),1,4) from testref;
And I would like to send string representing user defined type to application as a text not as a UDT. Can you advise me how to write a query that will return varchar2 representaion same as I can see in SQL*PLUS?
EDIT
My real case is using:
create or replace type reftypetab as table of reftype;
and query:
select cast(collect(c1) as reftypetab) from testref;
I would like to have that output either as varchar2: 'KACPER.REFTYPETAB(KACPER.REFTYPE(4,'asd','aaa'),KACPER.REFTYPE(3,'asf','baa'),KACPER.REFTYPE(2,'asg','aba'),KACPER.REFTYPE(1,'ash','aab'))' or as an XML. But when calling:
select xmltype(cast(collect(c1) as reftypetab)) from testref;
I got:
ORA-06553: PLS-306: wrong number or types of arguments in call to 'XMLTYPE'
Do you have any suggestions how can I get XML or text representation of my tabletype?
You can use this one:
SELECT T.c1.ID, T.c1.NAME, T.c1.details
FROM TESTREF T;
If you like to get all in one (XML string) you can also use
SELECT XMLTYPE(c1)
FROM TESTREF;
Another way is this one:
CREATE OR REPLACE TYPE reftype IS OBJECT (ID NUMBER, NAME VARCHAR2(40), details VARCHAR2(1000),
MEMBER FUNCTION TO_VARCHAR2 RETURN VARCHAR2);
CREATE OR REPLACE TYPE BODY reftype IS
MEMBER FUNCTION TO_VARCHAR2 RETURN VARCHAR2 IS
BEGIN
RETURN SELF.ID||','||SELF.NAME||','||SELF.details;
END TO_VARCHAR2;
END;
/
SELECT t.c1.TO_VARCHAR2()
FROM TESTREF t;
Try something like this:
select t.c1.id||','||t.c1.name||','||t.c1.details text
from testref t;
TEXT
----------------
4,asd,aaa
3,asf,baa
2,asg,aba
1,ash,aab
NB For reasons I've never understood, the explicit table alias is mandatory - i.e. the following will not work:
-- No alias:
select c1.id||','||c1.name||','||c1.details text
from testref;
-- Implicit use of table name as alias:
select testref.c1.id||','||testref.c1.name||','||testref.c1.details text
from testref;

Oracle SQL: select from table with nested table

I wonder how can i make select statement from table which have a typed column ?
Type of this column is defined as:
create or replace TYPE "MYCOL" as table of MYTYPE;
create or replace TYPE "MYTYPE" as OBJECT
( myid Number, myname Varchar2);
UPD1
Table is defined as
CREATE TABLE "T_TABLE"
( "ID" NUMBER NOT NULL ENABLE, "NAME" "MYCOL" )
If i select this column with select * from T_TABLE i will get this not informative result:
1, MYSCHEMA.MYCOL([MYSCHEMA.MYTYPE],[MYSCHEMA.MYTYPE])
I want just to unwrap this types.
Try it like this:
select t."ID", tt.myid, tt.myname
from "T_TABLE" t, table(t."NAME") tt;
Here is a sqlfiddle demo