Создать PL/SQL-скрипт с 2 курсорами, параметром и выдать результаты из таблицы?

Мне нужно создать сценарий, который помещает номер ключа из таблицы A (который будет использоваться в качестве параметра позже), затем передает этот параметр или номер ключа в запрос, а затем сбрасывает эти результаты в запись хранения или таблицу для последующей обработки и такой. Поскольку каждая выборка содержит более 1 строки (на самом деле на результат запроса или на ключ утверждения приходится 6 строк), я решил использовать предложение массового сбора. Хотя мой первоначальный тест с другой базой данных сработал, я еще не понял, почему настоящий скрипт не работает.

Вот тестовый скрипт, который я использовал:

DECLARE

--Cursors--
CURSOR prod_id is select distinct(product_id) from product order by 1 asc;

CURSOR cursorValue(p_product_id NUMBER) IS
        SELECT h.product_description,o.company_short_name
        FROM company o,product h
        WHERE o.product_id =h.product_id
        AND h.product_id =p_product_id
        AND h.product_id IS NOT NULL
        ORDER by 2;

    --Table to store Cursor data--        
    TYPE indx IS TABLE OF cursorValue%ROWTYPE
    INDEX BY PLS_INTEGER;
    indx_tab  indx;

    ---Variable objects---
    TotalIDs PLS_INTEGER;
    TotalRows PLS_INTEGER := 0 ;

BEGIN
      --PARAMETER CURSOR RUNS---
    FOR prod_id2 in prod_id LOOP
    dbms_output.put_line('Product ID: ' || prod_id2.product_id);
    TotalIDs := prod_id%ROWCOUNT;

          --FLOW PARAMETER TO SECOND CURSOR--
        Open cursorValue(prod_id2.product_id);
        Loop 
        Fetch cursorValue Bulk collect into indx_tab;

          ---data dump into table---
        --dbms_output.put_line('PROD Description: ' || indx_tab.product_description|| ' ' ||'Company Name'|| indx_tab.company_short_name);
        TotalRows := TotalRows + cursorValue%ROWCOUNT;
        EXIT WHEN cursorValue%NOTFOUND;
        End Loop;
        CLOSE cursorValue;
    End Loop;    
dbms_output.put_line('Product ID Total: ' || TotalIDs);
dbms_output.put_line('Description Rows: ' || TotalRows);
END;


Test Script Results:
anonymous block completed
Product ID: 1
Product ID: 2
Product ID: 3
Product ID: 4
Product ID: 5
Product ID Total: 5
Description Rows: 6

Обновление: пометка вопроса как «отвеченного». Спасибо.


person Asian Man    schedule 15.09.2014    source источник
comment
Вы задаете несколько вопросов, вроде как, но я ответил на то, что кажется наиболее актуальным. Поскольку ваш тестовый блок работает, вы, кажется, уже знаете, как использовать массовый сбор (хотя, похоже, вы удалили loop, возможно, вместо того, чтобы комментировать его). Я не уверен, есть ли у вас какие-либо дополнительные проблемы после исправления опечатки, но если это так, вам следует задать отдельный вопрос, показывающий текущее и желаемое поведение вашего реального блока. dbms_output действительно следует использовать только для базовой отладки, поскольку клиенты могут не отображать вывод - хотя не уверен, что вы хотите делать с данными.   -  person Alex Poole    schedule 16.09.2014
comment
Итак, исправил опечатку (спасибо, что сначала не заметил). Теперь ошибка выглядит следующим образом: Отчет об ошибке: ORA-06550: строка 41, столбец 43: PLS-00302: компонент «CLAIM_NUM» должен быть объявлен ORA-06550: строка 41, столбец 11: PL/SQL: оператор SQL игнорируется 06550. 00000 - строка %s, столбец %s:\n%s *Причина: Обычно ошибка компиляции PL/SQL. *Действие:   -  person Asian Man    schedule 16.09.2014
comment
По сути, я хочу, чтобы строки (более одной) из второй группы курсоров были собраны в таблицу, чтобы операторы case могли ссылаться на столбцы в таблице.   -  person Asian Man    schedule 16.09.2014
comment
Итак, строка 41 относится к CUR_CLAIMNUM2.CLAIM_NUM; но курсор выбирает CLAIM_NO. Точно такая же ошибка. Извините, но это действительно базовая отладка - посмотрите на ошибку, найдите номер строки в коде, посмотрите, что описано в тексте ошибки...   -  person Alex Poole    schedule 16.09.2014
comment
Как и было предложено, я внимательно посмотрел на код и внес несколько изменений (также в соответствии с предложениями) без каких-либо ошибок. Однако остается вопрос: нужно ли объявлять запись с тем же %ROWTYPE, что и второй курсор, чтобы таблица отображала столбцы? :   -  person Asian Man    schedule 16.09.2014
comment
Не меняйте полностью вопрос. Ответ сейчас не имеет смысла; а новый однострочный вопрос не содержит информации или подробностей и на него невозможно ответить. Пожалуйста, верните вопрос (в предыдущей версии есть кнопка отката). Если непосредственная проблема, о которой вы спрашивали (и связанная с ней вторая проблема, которая также была опечаткой), решена, примите ответ и задайте новый вопрос.   -  person Alex Poole    schedule 16.09.2014
comment
Я пытался это сделать, но это не работает.   -  person Asian Man    schedule 16.09.2014
comment
Я пытался добавить свои обновления, но получаю другие ошибки. Кроме того, я отправил модератору еще одно сообщение с флагом об ошибках, которые я получал.   -  person Asian Man    schedule 16.09.2014
comment
Почему вы продолжаете удалять важные части вопроса?   -  person Alex Poole    schedule 17.09.2014
comment
Я пытался поговорить с вами, но некоторые из элементов, которыми поделились, были конфиденциальной информацией, поэтому я удалил их. Сначала я пытался изменить его, но продолжал получать сообщения об ошибках.   -  person Asian Man    schedule 17.09.2014


Ответы (1)


Первая ошибка в строке 7. В строке 4 у вас есть:

  CURSOR CUR_CLAIMNUM IS
                      SELECT DISTINCT(CLAIM_NO)FROM R7_OPENCLAIMS;

... и это кажется правильным, поэтому имя вашего столбца CLAIM_NO. В строке 7:

  CURSOR OPEN_CLAIMS (CLAIM_NUM  R7_OPENCLAIMS.CLAIM_NUM%TYPE)  IS

... так что вы неправильно напечатали имя столбца как CLAIM_NUM, которого нет в этой таблице. Это то, что сообщение об ошибке говорит вам, на самом деле.

Другие ошибки связаны с тем, что курсор недействителен из-за этой опечатки.

Когда вы открываете второй курсор, у вас возникает такая же путаница имени:

          OPEN OPEN_CLAIMS (CUR_CLAIMNUM2.CLAIM_NUM);

... что не удается, потому что курсор запрашивает CLAIMNO, а не CLAIMNUM; за исключением того, что здесь его еще больше смущает distinct. Вы не указали псевдоним имени столбца, поэтому Oracle применяет его, на который вы могли бы сослаться, но проще добавить свой собственный:

  CURSOR CUR_CLAIMNUM IS
                      SELECT DISTINCT(CLAIM_NO) AS CLAIM_NO FROM R7_OPENCLAIMS;

а потом

          OPEN OPEN_CLAIMS (CUR_CLAIMNUM2.CLAIM_NO);

Но я бы посоветовал вам также изменить имя курсора с CUR_CLAIMNUM на CUR_CLAIM_NO как в определении, так и в объявлении цикла. И иметь итератор курсора с именем CUR_CLAIMNUM2 странно, поскольку он предполагает, что это имя курсора; может быть что-то вроде ROW_CLAIM_NO было бы понятнее.

person Alex Poole    schedule 15.09.2014