Как извлечь sys_refcursor в таблицу асоциативных массивов в PL / SQL - PullRequest
1 голос
/ 24 мая 2019

Имея такие определения:

TYPE type_record1 IS RECORD(
id NUMBER,
value NUMBER
);

v_count NUMBER;

TYPE tp_arr_record IS TABLE OF type_record1 INDEX BY PLS_INTEGER;

v_t_arr_record   tp_arr_record;

v_results sys_refcursor;

И

v_results := f_execute_cursor(id_process);

Как я могу получить этот слабый курсор (v_results) с помощью асоциативного массива, подобного этой форме:

FOR idx IN v_results 
    LOOP
      v_count   :=  v_count + 1;
      v_t_arr_record(v_count).id      :=  idx.id;
      v_t_arr_record(v_count).value   :=  idx.value;
    END LOOP;

Другими словами, как можно извлечь из sys_refcursor в асоциативный массив без использования записи, потому что мне нужно получить набор данных из курсора?

1 Ответ

1 голос
/ 25 мая 2019

Используя почти тот же код, который я использовал при ответе на другой ваш пост , он берет Продукты, возвращаемые вашей Функцией, и сохраняет значения в коллекции.

Пожалуйстадайте мне знать, если вам нужны разъяснения или у вас есть другие вопросы относительно моего ответа здесь.

DECLARE

  /* Store Ref Cursor returned by f_process_data() Function */
  v_result_cursor   SYS_REFCURSOR;

  /* Declare Record so we can store the data FETCHed from the Cursor */
  rec_product       products%ROWTYPE;

  /* Declare Type based off of products table */
  TYPE  t_products  IS TABLE OF products%ROWTYPE;

  /* Declare Table based off of Type t_products and initialize it. */
  tab_products      t_products   :=    t_products();

  /* Declare a couple Product Variables for Proof of Concept */
  v_sausage         NUMBER;
  v_ham             NUMBER;

  /* Store output */
  n_id              NUMBER;
  v_id_product      VARCHAR2(100);

  /* Declare Type of TABLE NUMBER */
  TYPE  nt_type IS TABLE OF NUMBER;

  /* Create Array/Table/Collection of type nt_type to store product ids */
  nt_product_ids    nt_type;

  /* Returns a Ref Cursor based on the product_id used as Input to this function */
  FUNCTION f_process_data(p_id_process IN NUMBER, p_id_product IN NUMBER)
  RETURN SYS_REFCURSOR
  AS
    /* Declare Ref Cursor that will be Returned */
    rc_result_cursor   SYS_REFCURSOR;    

  BEGIN 
    /* Open Ref Cursor based on Product ID parameter */
    OPEN rc_result_cursor FOR SELECT * FROM products WHERE item_id = p_id_product;

    RETURN rc_result_cursor;

  END f_process_data
  ;

BEGIN

  /* Set Product Variables to IDs */
  v_sausage       := 2003;
  v_ham           := 2007;

  /* Store product ids into a Number Table so we can Loop thru it */
  nt_product_ids  :=  nt_type (v_sausage,v_ham);

  FOR r IN nt_product_ids.FIRST .. nt_product_ids.LAST
  LOOP
    /* Get Ref Cursor using SINGLE Product ID */
    v_result_cursor := f_process_data(1, nt_product_ids(r));

    LOOP

      FETCH v_result_cursor INTO rec_product;

      n_id            :=  rec_product.item_id;
      v_id_product    :=  rec_product.item;

      EXIT WHEN v_result_cursor%NOTFOUND;

      --dbms_output.put_line('Product_id: ' || n_id);
      --dbms_output.put_line('Product: ' || v_id_product); 

      /* Store data into Collection */
      tab_products.EXTEND(1);          
      /* Set the Row inside the tab_products Table at the newly extended Index to the record rec_product */
      tab_products(tab_products.COUNT)  :=  rec_product;

    END LOOP; /* Cursor Loop */

    /* Close Cursor */
    CLOSE v_result_cursor;

  END LOOP; /* Product IDs Loop */

dbms_output.put_line('Total Products in tab_products COllECTION: ' || tab_products.COUNT);

/* Now we can just loop thru our tab_products Collection */
For r IN tab_products.FIRST .. tab_products.LAST
LOOP

  dbms_output.put_line('Product: ' || tab_products(r).item_id ||' - ' || tab_products(r).item);

END LOOP;

EXCEPTION WHEN OTHERS
  THEN CLOSE v_result_cursor;

END;
...