CREATE TABLE limbs
(
nm VARCHAR2 (100),
avg_len NUMBER
)
Table created.
BEGIN
INSERT INTO limbs VALUES ('arm', 1);
INSERT INTO limbs VALUES ('leg', 2);
INSERT INTO limbs VALUES ('tail', 3);
COMMIT;
END;
1 row(s) inserted.
CREATE OR REPLACE TYPE limb_ot AUTHID DEFINER
IS OBJECT
(
nm VARCHAR2 (100),
avg_len NUMBER
)
Type created.
Works Just Fine
DECLARE
TYPE limbs_t IS TABLE OF limb_ot;
l_limbs limbs_t;
BEGIN
SELECT limb_ot (l.nm, l.avg_len)
BULK COLLECT INTO l_limbs
FROM limbs l
ORDER BY l.nm;
l_limbs := l_limbs MULTISET UNION l_limbs;
DBMS_OUTPUT.put_line ('Lots of limbs! ' || l_limbs.COUNT);
END;
Statement processed.
Lots of limbs! 6
Even Works for %ROWTYPE Elements!
DECLARE
TYPE limbs_t IS TABLE OF limbs%ROWTYPE;
l_limbs limbs_t;
BEGIN
SELECT l.nm, l.avg_len
BULK COLLECT INTO l_limbs
FROM limbs l
ORDER BY l.nm;
l_limbs := l_limbs MULTISET UNION l_limbs;
DBMS_OUTPUT.put_line ('Lots of limbs! ' || l_limbs.COUNT);
END;
Statement processed.
Lots of limbs! 6
EXCEPT Requires Comparison
DECLARE
TYPE limbs_t IS TABLE OF limb_ot;
l_limbs limbs_t;
BEGIN
SELECT limb_ot (l.nm, l.avg_len)
BULK COLLECT INTO l_limbs
FROM limbs l
ORDER BY l.nm;
l_limbs := l_limbs MULTISET EXCEPT l_limbs;
DBMS_OUTPUT.put_line ('Lots of limbs! ' || l_limbs.COUNT);
END;
ORA-06550: line 11, column 15: PLS-00306: wrong number or types of arguments in call to 'MULTISET_EXCEPT_ALL'More Details: https://docs.oracle.com/error-help/db/ora-06550
UNION DISTINCT - Compares
DECLARE
TYPE limbs_t IS TABLE OF limb_ot;
l_limbs limbs_t;
BEGIN
SELECT limb_ot (l.nm, l.avg_len)
BULK COLLECT INTO l_limbs
FROM limbs l
ORDER BY l.nm;
l_limbs := l_limbs MULTISET UNION DISTINCT l_limbs;
DBMS_OUTPUT.put_line ('Lots of limbs! ' || l_limbs.COUNT);
END;
ORA-06550: line 10, column 15: PLS-00306: wrong number or types of arguments in call to 'MULTISET_UNION_DISTINCT'More Details: https://docs.oracle.com/error-help/db/ora-06550
Add a Map Method!
CREATE OR REPLACE TYPE limb_ot AUTHID DEFINER
IS OBJECT
(
nm VARCHAR2 (100),
avg_len NUMBER,
MAP MEMBER FUNCTION limb_map
RETURN NUMBER
)
Type created.
CREATE OR REPLACE TYPE BODY limb_ot
IS
MAP MEMBER FUNCTION limb_map
RETURN NUMBER
IS
BEGIN
RETURN LENGTH (self.nm);
END;
END;
Type created.
Now UNION DISTINCT Works
DECLARE
TYPE limbs_t IS TABLE OF limb_ot;
l_limbs limbs_t;
BEGIN
SELECT limb_ot (l.nm, l.avg_len)
BULK COLLECT INTO l_limbs
FROM limbs l
ORDER BY l.nm;
l_limbs := l_limbs MULTISET UNION DISTINCT l_limbs;
DBMS_OUTPUT.put_line ('Lots of limbs! ' || l_limbs.COUNT);
END;
Statement processed.
Lots of limbs! 2
DECLARE
TYPE limbs_t IS TABLE OF limb_ot;
l_limbs limbs_t;
BEGIN
SELECT limb_ot (l.nm, l.avg_len)
BULK COLLECT INTO l_limbs
FROM limbs l
ORDER BY l.nm;
l_limbs := l_limbs MULTISET EXCEPT l_limbs;
DBMS_OUTPUT.put_line ('Lots of limbs! ' || l_limbs.COUNT);
END;
Statement processed.
Lots of limbs! 0
But Still Not with %ROWTYPE
DECLARE
TYPE limbs_t IS TABLE OF limbs%ROWTYPE;
l_limbs limbs_t;
BEGIN
SELECT l.nm, l.avg_len
BULK COLLECT INTO l_limbs
FROM limbs l
ORDER BY l.nm;
l_limbs := l_limbs MULTISET EXCEPT l_limbs;
DBMS_OUTPUT.put_line ('Lots of limbs! ' || l_limbs.COUNT);
END;
ORA-06550: line 11, column 15: PLS-00306: wrong number or types of arguments in call to 'MULTISET_EXCEPT_ALL'More Details: https://docs.oracle.com/error-help/db/ora-06550
Tweak Mapping Algorithm
CREATE OR REPLACE TYPE BODY limb_ot
IS
MAP MEMBER FUNCTION limb_map
RETURN NUMBER
IS
BEGIN
RETURN LENGTH (self.nm) + self.avg_len;
END;
END;
Type created.
Mapping Algorithms Matter
DECLARE
TYPE limbs_t IS TABLE OF limb_ot;
l_limbs limbs_t;
BEGIN
SELECT limb_ot (l.nm, l.avg_len)
BULK COLLECT INTO l_limbs
FROM limbs l
ORDER BY l.nm;
l_limbs := l_limbs MULTISET UNION DISTINCT l_limbs;
DBMS_OUTPUT.put_line ('Lots of limbs! ' || l_limbs.COUNT);
END;
Statement processed.
Lots of limbs! 3