Reputation: 6323
I have the following structure below and I want to add a record into project
table. The problem with the following INSERT is that on the place of customer_t
I have to select a record from user
table while inserting but I want to select only customers (and not staff members). Basically customer_t
and staff_t
inherit from user_t
(table: user).
You can look at same insert but for service_t, it works fine because I'm selecting from a table, but in this case, there is no table for customer.
I'm not so experience with this ORM. Any idea how to solve it?
INSERT INTO project VALUES (
1,
'Project name',
'Description',
( SELECT REF(u) AS customer_t
FROM "USER" u
WHERE idno = 1
AND VALUE(u) IS OF TYPE (customer_t)
),
( SELECT REF(s) FROM service s WHERE serviceno = 1)
);
Error message:
Error starting at line : 1 in command -
INSERT INTO project VALUES (1, 'Project name', 'Logo', (SELECT REF(u) AS customer_t FROM "USER" u WHERE idno = 1 AND VALUE(u) IS OF TYPE (customer_t)), (SELECT REF(s) FROM service s WHERE serviceno = 1))
Error at Command Line : 1 Column : 72
Error report -
SQL Error: ORA-00932: inconsistent datatypes: expected REF C##EX_TEST.CUSTOMER_T got REF C##EX_TEST.USER_T
00932. 00000 - "inconsistent datatypes: expected %s got %s"
*Cause:
*Action:
SQL:
CREATE TYPE name_t AS OBJECT (
first_name VARCHAR2(32),
last_name VARCHAR2(32)
);
CREATE TYPE address_t AS OBJECT (
province VARCHAR2(32),
street VARCHAR2(32),
city VARCHAR2(32),
postal_code VARCHAR2(10)
);
CREATE TYPE user_t AS OBJECT (
idno NUMBER,
email VARCHAR2(40),
password VARCHAR2(32),
name name_t,
address address_t,
phone VARCHAR2(15),
MAP MEMBER FUNCTION get_idno RETURN NUMBER
) NOT FINAL;
CREATE TYPE rank_t AS OBJECT (
rankno NUMBER,
name VARCHAR2(40),
description VARCHAR2(60)
);
CREATE TABLE "RANK" OF rank_t (
PRIMARY KEY (rankno),
UNIQUE (name)
);
INSERT INTO "RANK" VALUES (1, 'User', 'Simple a user');
INSERT INTO "RANK" VALUES (2, 'Manager', 'Manager');
INSERT INTO "RANK" VALUES (3, 'Administrator', 'Admin');
CREATE TYPE customer_t UNDER user_t (
);
CREATE TYPE staff_t UNDER user_t (
salary NUMBER(7,2),
rank REF rank_t
);
CREATE TABLE "USER" OF user_t (
PRIMARY KEY (idno),
UNIQUE (email));
CREATE TYPE service_t AS OBJECT (
serviceno NUMBER,
name VARCHAR2(40),
description VARCHAR2(60)
);
CREATE TABLE service OF service_t (PRIMARY KEY (serviceno));
CREATE TYPE project_t AS OBJECT (
projectno NUMBER,
name VARCHAR2(40),
description VARCHAR2(60),
customer REF customer_t,
service REF service_t
);
CREATE TABLE project OF project_t (PRIMARY KEY (projectno));
Upvotes: 0
Views: 268
Reputation: 167981
You don't need a separate table for a customers; just insert the types into the USER
table.
If you want to put a customer in then insert a customer_t
type:
INSERT INTO "USER" VALUES(
customer_t(
1,
'[email protected]',
'abcdefg',
name_t( 'One', 'Uno' ),
address_t( 'province','street', 'city', '12345' ),
'0123456789'
)
);
If you want to insert a user then use user_t
or insert values without a type:
INSERT INTO "USER" VALUES(
2,
'[email protected]',
'abcdefg',
name_t( 'Two', 'Dos' ),
address_t( 'province','street', 'city', '12345' ),
'0123456789'
);
If you want to insert a staff member then use staff_t
:
INSERT INTO "USER" VALUES(
staff_t(
3,
'[email protected]',
'abcdefg',
name_t( 'Three', 'Tres' ),
address_t( 'province','street', 'city', '12345' ),
'0123456789',
12345.67,
(SELECT REF(r) FROM "RANK" r WHERE rankno = 2 )
)
);
Then the data will have the correct types (which you can extract using SYS.ANYDATA
) and use the TREAT
function to convert a super-type to a sub-type:
SELECT idno,
email,
SYS.ANYDATA.getTypeName( SYS.ANYDATA.convertObject( VALUE(u) ) ) As type,
TREAT(VALUE(u) AS staff_t).salary AS salary,
TREAT(VALUE(u) AS staff_t).rank.name AS rank
FROM "USER" u
outputs:
IDNO | EMAIL | TYPE | SALARY | RANK ---: | :--------------------------- | :------------------------------------- | -------: | :------ 1 | [email protected] | FIDDLE_KPHUNVHPVRKOYQBWVAQS.CUSTOMER_T | null | null 2 | [email protected] | FIDDLE_KPHUNVHPVRKOYQBWVAQS.USER_T | null | null 3 | [email protected] | FIDDLE_KPHUNVHPVRKOYQBWVAQS.STAFF_T | 12345.67 | Manager
and:
SELECT idno,
email
FROM "USER" u
WHERE VALUE(u) IS OF TYPE (customer_t)
outputs:
IDNO | EMAIL ---: | :--------------------------- 1 | [email protected]
and your insert needs to convert the REF
from the user_t
super-type to the customer_t
sub-type using the TREAT
function:
INSERT INTO project VALUES (
1,
'Project name',
'Description',
( SELECT TREAT( REF(u) AS REF customer_t )
FROM "USER" u
WHERE idno = 1
AND VALUE(u) IS OF TYPE (customer_t)
),
( SELECT REF(s) FROM service s WHERE serviceno = 1)
);
db<>fiddle here
Upvotes: 1