Oracle - Как добавить запись в коллекцию того же типа (Multiset Union) - PullRequest
0 голосов
/ 25 апреля 2019

Я использовал MULTISET UNION для загрузки коллекции в другую коллекцию того же типа, однако сейчас я работаю с записями и хочу добавить запись в Коллекция того же типа.По какой-то причине я просто не могу понять подходящий синтаксис или просто правильный способ сделать это, поскольку MULTISET UNION, кажется, не очень хорошо работает с записями, как я привык работать с коллекциями.

IДобавил краткое описание того, как этот код работает в конце (должен работать в любом случае).

Снимок экрана и код ниже

LINE 44: c_los_ms_tbl_ret := c_los_ms_tbl_ret MULTISET UNION los_ms_row;

enter image description here

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() a Строка объявляется с именем 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'

1 Ответ

1 голос
/ 25 апреля 2019

MULTISET UNION используется для создания одной вложенной таблицы из двух вложенных таблиц. Вы пытаетесь использовать MULTISET UNION для объединения вложенной таблицы и одной записи.

Есть два способа исправить это:

  1. Создайте таблицу из одного элемента из одной записи:

        c_los_ms_tbl_ret  := c_los_ms_tbl_ret MULTISET UNION t_los_ms_tbl(los_ms_row);
    
  2. Откажитесь от использования MULTISET UNION и просто добавьте новую запись в таблицу:

        c_los_ms_tbl_ret.EXTEND(1);
        c_los_ms_tbl_ret(c_los_ms_tbl_ret.COUNT) := los_ms_row;
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...