Sì. È necessario racchiudere le colonne nel costruttore dell'oggetto e utilizzare BULK COLLECT
opzione nel SELECT
dichiarazione:
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;
Per inciso, devi anche assicurarti di creare la specifica dell'oggetto, non solo il corpo (come nel tuo esempio).
Colonne in SELECT
devono essere nello stesso ordine in cui si trovano nel costruttore dell'oggetto. Se non hai definito in modo esplicito un costruttore, ne esiste uno esplicitamente con ciascuna colonna nell'ordine dichiarato nella specifica.
L'unico aspetto negativo dell'utilizzo di questa funzionalità è che un numero elevato di righe comporterà un utilizzo intenso della memoria. Se prevedi di usarlo per elaborare un numero elevato di righe, dovresti utilizzare un ciclo con LIMIT
clausola.
È possibile specificare un costruttore esplicito, oltre all'elenco di colonne trovato nella specifica. Il costruttore può avere qualsiasi input tu definisca, quindi, ovviamente, quando usi un costruttore esplicito, devi seguire la sua lista di argomenti. Ecco un esempio:
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;