Я использовал MULTISET UNION
, чтобы загрузить коллекцию в другую коллекцию того же типа, однако сейчас я работаю с Записями и хочу добавить Запись в Коллекцию. того же типа. По какой-то причине я просто не могу понять подходящий синтаксис или просто правильный способ сделать это, поскольку MULTISET UNION, похоже, не очень хорошо работает с записями так, как я привык работать с коллекциями.
В конце я добавил краткое описание того, как работает этот код (все равно он должен работать).
Скриншот и код ниже
LINE 44: c_los_ms_tbl_ret := c_los_ms_tbl_ret MULTISET UNION los_ms_row;
DECLARE
TYPE t_los_ms_rec IS RECORD(
appt_id NUMBER DEFAULT NULL,
appt_name VARCHAR(300) DEFAULT NULL,
tot_units NUMBER DEFAULT 0,
new_rentals NUMBER DEFAULT 0,
term_rentals NUMBER DEFAULT 0,
avg_los_all NUMBER DEFAULT 0
);
TYPE t_los_ms_tbl IS TABLE OF t_los_ms_rec;
/* Two collections based on Table Type of Record t_los_ms_rec */
c_los_ms_tbl_ret t_los_ms_tbl := t_los_ms_tbl();
c_los_ms_tbl t_los_ms_tbl := t_los_ms_tbl();
FUNCTION los_func(p_appt_ids IN VARCHAR) RETURN t_los_ms_tbl
IS
los_ms_row t_los_ms_rec; /* Declare Row based on Record Type */
BEGIN
/* Outer loop: iterate through all user selected appartments. */
FOR los IN
(
SELECT 1001 AS appt_id, 45 AS tot_units, 10 AS new_rentals, 3 AS term_rentals, 'Building1' AS appt_name
FROM dual UNION ALL
SELECT 1002 AS appt_id, 37 AS tot_units, 6 AS new_rentals, 4 AS term_rentals, 'Building2' AS appt_name
FROM duaL
)
LOOP
/* Set Row Fields to the Data being returned by Outer Loop. Fake Table data from dual. */
los_ms_row.appt_name := los.appt_name;
los_ms_row.appt_id := los.appt_id;
los_ms_row.new_rentals := los.new_rentals;
los_ms_row.term_rentals := los.term_rentals;
los_ms_row.tot_units := los.tot_units;
los_ms_row.avg_los_all := 45; /* Made up Number */
/* Output Apartment Name for testing */
dbms_output.put_line('Apartment Name' || los_ms_row.appt_name);
/* Save Row Data into Collection */ /* HOW DO I POPULATE COLLECTION WITH A RECORD */
c_los_ms_tbl_ret := c_los_ms_tbl_ret MULTISET UNION los_ms_row;
END LOOP;
RETURN c_los_ms_tbl_ret; /* Return Populated Collection */
END los_func;
BEGIN
/* Call Function and Store Returned Collection into a collection of same type */
c_los_ms_tbl := los_func(p_appt_ids => '1001,1002');
FOR r IN c_los_ms_tbl.FIRST .. c_los_ms_tbl.LAST
LOOP
dbms_output.put_line(c_los_ms_tbl(r).avg_los_all);
END LOOP;
END;
Сводка
- Объявлен тип записи.
t_los_ms_rec
- Тип таблицы, объявленный на основе записи
t_los_ms_tbl
Две коллекции объявлены на основе типов таблиц
c_los_ms_tbl_ret
иc_los_ms_tbl
В блоке BEGIN основного сценария функция
los_func()
, которая возвращает коллекцию типа t_los_ms_tbl, вызывается с использованием идентификаторов апартаментов в качестве параметров.LINE 20:
Внутриlos_func()
объявляется строка с именемlos_ms_row
того же типаt_los_ms_rec
. Поля этой строки заполняются фальшивыми данными.- Далее нужно заполнить коллекцию по одной строке за раз. Не могу понять.
- В этот момент при комментировании
LINE 44
, где я пытаюсь заполнить коллекцию, имена апартаментов успешно отправляются в dbms_output. Здесь он ломается из-за того, что я не знаю, как получить запись, которая успешно заполняется данными, в коллекциюc_los_ms_tbl_ret
.
Сообщение об ошибке -
ORA-06550: строка 44, столбец 32: PLS-00306: неправильное количество или типы аргументов при вызове «MULTISET_UNION_ALL»