Oracle - How to add a Record to a Collection of the same Type (Multiset Union)

北战南征 提交于 2019-12-11 18:30:45

问题


I have used MULTISET UNION in order to load a collection into another collection of the same type however I am now working with Records and want to add a Record into a Collection of the same Type. For whatever reason I just can't figure out the appropriate syntax or simply the proper way to do this as MULTISET UNION appears to not play nice with Records in the way I'm used to working with Collections.

I've added a summary of how this code works at the end (supposed to work anyway).

Screenshot and Code Below

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;

Summary

  • Record Type is Declared. t_los_ms_rec
  • Table Type Declared based on Record t_los_ms_tbl
  • Two Collections Declared based on Table Type c_los_ms_tbl_ret and c_los_ms_tbl

  • In the BEGIN block of the Main script the Function los_func() that returns a Collection of type t_los_ms_tbl is called using the Apartment IDs as it's parameters.

  • LINE 20: Within los_func() a Row is Declared named los_ms_row of the Same Type t_los_ms_rec. The fields of this Row are populated using Fake Data.
  • Next is to Populate the Collection one Row at a time. Can't figure this out.
  • At this point when commenting out LINE 44 where I attempt to populate the collection the Apartment names are successfully being sent to the dbms_output. This is where it breaks due to me not knowing how to get the Record which is successfully being populated with data into the Collection c_los_ms_tbl_ret.

Error report -

ORA-06550: line 44, column 32: PLS-00306: wrong number or types of arguments in call to 'MULTISET_UNION_ALL'


回答1:


MULTISET UNION is used to create one nested table from two nested tables. You are trying to use MULTISET UNION to join together a nested table and a single record.

There are two ways you can fix this:

  1. Make a one-element table out of the single record:

        c_los_ms_tbl_ret  := c_los_ms_tbl_ret MULTISET UNION t_los_ms_tbl(los_ms_row);
    
  2. Forgo the use of MULTISET UNION and just append the new record to the table:

        c_los_ms_tbl_ret.EXTEND(1);
        c_los_ms_tbl_ret(c_los_ms_tbl_ret.COUNT) := los_ms_row;
    


来源:https://stackoverflow.com/questions/55855857/oracle-how-to-add-a-record-to-a-collection-of-the-same-type-multiset-union

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!