Как я могу вставить данные в таблицу с помощью ассоциативного массива?

Я заполнил ассоциативный массив информацией из курсора, и теперь я хотел бы вставить информацию об ассоциативном массиве в таблицу. Как это возможно? Считайте, что ассоциативный массив создан из записи.

SET SERVEROUTPUT ON

DECLARE
  TYPE rec_depts_info IS RECORD(
      v_dept_id   departments.department_id%TYPE,
      v_dept_name departments.department_name%TYPE);
  TYPE typ_depts_info IS TABLE OF rec_depts_info
      INDEX BY PLS_INTEGER;

  CURSOR cur_depts_info_1
  IS
     SELECT department_id, department_name
     FROM   departments
     WHERE  department_id   IS NOT NULL
     AND    department_name IS NOT NULL;

  t_depts_info_1 typ_depts_info;
  rec_depts_info_1 rec_depts_info;

  v_counter_1 PLS_INTEGER := 1;
  v_counter_2 PLS_INTEGER := 1;
BEGIN
  v_counter_1 := v_counter_1 + 1;

  FOR depts_info IN cur_depts_info_1
  LOOP
      t_depts_info_1(v_counter_1).v_dept_id   := depts_info.department_id;
      t_depts_info_1(v_counter_1).v_dept_name := depts_info.department_name;

      EXIT WHEN cur_depts_info_1%NOTFOUND;

  END LOOP;

  LOOP
    INSERT INTO tabla_pruebas
    VALUES(t_depts_info_1(v_counter_2).v_dept_id,
           t_depts_info_1(v_counter_2).v_dept_name)
    RETURNING column_1, column_2
    INTO      rec_depts_info_1.v_dept_id, rec_depts_info_1.v_dept_name;

    DBMS_OUTPUT.PUT_LINE('DEPT ID: ' || rec_depts_info_1(v_counter_2).v_dept_id
                         || ' DEPT NAME: ' ||
                         rec_depts_info_1(v_counter_2).v_dept_name);

    v_counter_2 := v_counter_2 + 1;

    EXIT WHEN SQL%NOTFOUND;
  END LOOP;
END;

Я пытаюсь вставить данные в новую таблицу, используя простой цикл, но получаю следующую ошибку:

Informe de error -
ORA-06550: line 51, column 41:
PLS-00222: no function with name 'REC_DEPTS_INFO_1' exists in this scope
ORA-06550: line 51, column 5:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

Спасибо!!!


person Community    schedule 01.02.2017    source источник
comment
Как вы интерпретируете ошибку PLS-0222?   -  person Dan Bracuk    schedule 01.02.2017
comment
Вы пытаетесь использовать здесь запись как массив rec_depts_info_1(v_counter_2).v_dept_id. Опции: используйте правильный массив t_depts_info_1(v_counter_2).v_dept_id или запись rec_depts_info_1.v_dept_id   -  person Konstantin Sorokin    schedule 01.02.2017
comment
Спасибо, но теперь я получил ошибку НЕТ ДАННЫХ НАЙДЕН.   -  person    schedule 01.02.2017
comment
Это результат того, что v_counter_1 начинается с 2, а второй счетчик начинается с 1. Почему вы увеличиваете v_counter_1 вне цикла?   -  person Konstantin Sorokin    schedule 01.02.2017
comment
Лучше использовать массовые операции (выбор и вставка) для индексированных таблиц. И какова настоящая цель этого блока кода?   -  person Konstantin Sorokin    schedule 01.02.2017
comment
Я не знал о BULK COLLECT. Сейчас читаю об этом. Спасибо за вашу помощь, сэр.   -  person    schedule 01.02.2017


Ответы (1)


Вместо явного цикла вы можете использовать массив FORALL синтаксис для одновременной вставки всех значений массива:

  FORALL i IN t_depts_info_1.first..t_depts_info_1.last
    INSERT INTO tabla_pruebas
    VALUES(t_depts_info_1(i).v_dept_id,
           t_depts_info_1(i).v_dept_name);

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

DECLARE
  TYPE rec_depts_info IS RECORD(
      v_dept_id   departments.department_id%TYPE,
      v_dept_name departments.department_name%TYPE);
  TYPE typ_depts_info IS TABLE OF rec_depts_info
      INDEX BY PLS_INTEGER;

  t_depts_info_1 typ_depts_info;
BEGIN
  SELECT department_id, department_name
  BULK COLLECT INTO t_depts_info_1
  FROM   departments
  WHERE  department_id   IS NOT NULL
  AND    department_name IS NOT NULL;

  FORALL i IN t_depts_info_1.first..t_depts_info_1.last
    INSERT INTO tabla_pruebas
    VALUES(t_depts_info_1(i).v_dept_id,
           t_depts_info_1(i).v_dept_name);
END;
/

Хотя в этом надуманном примере вам вообще не нужна коллекция или какой-либо PL / SQL, вы можете сделать простой insert...select:

INSERT INTO tabla_pruebas (column_1, column_2)
SELECT department_id, department_name
FROM   departments
WHERE  department_id   IS NOT NULL
AND    department_name IS NOT NULL;
person Alex Poole    schedule 01.02.2017
comment
Я понял!! Спасибо большое за вашу помощь. Мне нужно больше практиковаться в PLSQL !!! Это очень полезно. Еще раз спасибо!!! - person ; 01.02.2017