Oui c'est le cas. Vous devez envelopper vos colonnes dans le constructeur de l'objet et utiliser le BULK COLLECT
option dans le SELECT
déclaration :
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;
En passant, vous devez également vous assurer que vous créez la spécification de l'objet, pas seulement le corps (comme dans votre exemple).
Colonnes dans le SELECT
doivent être dans le même ordre qu'ils se trouvent dans le constructeur de l'objet. Si vous n'avez pas explicitement défini de constructeur, il en existe un explicitement avec chaque colonne dans l'ordre déclaré dans la spécification.
Le seul inconvénient de l'utilisation de cette fonctionnalité est qu'un grand nombre de lignes entraînera une utilisation intensive de la mémoire. Si vous prévoyez de l'utiliser pour traiter un grand nombre de lignes, vous devez utiliser une boucle avec le LIMIT
clause.
Il est possible de spécifier un constructeur explicite, en plus de la liste de colonnes trouvée dans la spécification. Le constructeur peut avoir n'importe quelle entrée que vous définissez, donc, évidemment, lorsque vous utilisez un constructeur explicite, vous devez suivre sa liste d'arguments. Voici un exemple :
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;