Tak to jest. Musisz owinąć swoje kolumny w konstruktorze obiektu i użyć BULK COLLECT
opcja w SELECT
oświadczenie:
CREATE OR REPLACE TYPE t_some_type AS OBJECT(f varchar2(10))
/
CREATE OR REPLACE TYPE t_some_table IS TABLE OF t_some_type
/
DECLARE
v_some_table t_some_table;
BEGIN
SELECT t_some_type (dummy)
BULK COLLECT INTO v_some_table
FROM DUAL;
END;
Na marginesie, musisz również upewnić się, że tworzysz specyfikację obiektu, a nie tylko ciało (jak w twoim przykładzie).
Kolumny w SELECT
muszą być w tej samej kolejności, w jakiej znajdują się w konstruktorze obiektu. Jeśli nie zdefiniowałeś jawnie konstruktora, jest on jawnie obecny w każdej kolumnie w kolejności zadeklarowanej w specyfikacji.
Jedyną wadą korzystania z tej funkcji jest to, że duża liczba wierszy spowoduje duże zużycie pamięci. Jeśli zamierzasz użyć tego do przetwarzania dużej liczby wierszy, powinieneś użyć pętli z LIMIT
klauzula.
Możliwe jest określenie jawnego konstruktora, oprócz listy kolumn znajdującej się w specyfikacji. Konstruktor może mieć dowolne dane wejściowe, które zdefiniujesz, więc oczywiście, gdy używasz jawnego konstruktora, musisz postępować zgodnie z jego listą argumentów. Oto przykład:
CREATE OR REPLACE TYPE t_some_type AS OBJECT
(
f1 VARCHAR2 (10),
CONSTRUCTOR FUNCTION t_some_type (p_length NUMBER, p_value VARCHAR2)
RETURN SELF AS RESULT
);
/
CREATE OR REPLACE TYPE BODY t_some_type AS
CONSTRUCTOR FUNCTION t_some_type (p_length NUMBER, p_value VARCHAR2)
RETURN SELF AS RESULT IS
BEGIN
self.f1 := LPAD (p_value, p_length, p_value);
RETURN;
END t_some_type;
END;
/
CREATE OR REPLACE TYPE t_some_table IS TABLE OF t_some_type
/
DECLARE
v_some_table t_some_table;
BEGIN
--Explicit Constructor
SELECT t_some_type (10, dummy)
BULK COLLECT INTO v_some_table
FROM DUAL;
DBMS_OUTPUT.put_line (v_some_table (1).f1);
--Implicit Constructor
SELECT t_some_type (dummy)
BULK COLLECT INTO v_some_table
FROM DUAL;
DBMS_OUTPUT.put_line (v_some_table (1).f1);
END;