вставка строки в таблицу с помощью курсора PL / SQL

#oracle #plsql

#Oracle #plsql

Вопрос:

У меня есть эта процедура в пакете. проблема пакета заключается в том, что эта процедура не вставляет строку в таблицу

ПРОЦЕДУРА bcy_alimenta_supporto_G2 ЯВЛЯЕТСЯ

 CURSOR cur_request IS (
      SELECT p.concurrent_program_name,
         u.user_name,
         u.user_id,
         r.conc_login_id,
         r.request_id,
         r.request_date,
         r.phase_code,
         r.status_code,
         r.actual_completion_date,
         r.argument1,
         r.argument2,
         r.argument3,
         r.argument4,
         r.argument5,
         r.argument6,
         r.argument7,
         r.argument8,
         r.argument9,
         r.argument10
    FROM fnd_concurrent_requests r
         JOIN fnd_concurrent_programs p
            ON p.concurrent_program_id = r.concurrent_program_id
         JOIN fnd_user u ON u.user_id = r.requested_by
         JOIN bcy_concurrent_garante_2 bcg
            ON p.concurrent_program_name = bcg.concurrent_program_name
   WHERE     1 = 1
         AND r.request_date >= trunc(SYSDATE) - 2
         AND r.request_date >= g_start_date
         AND r.phase_code = 'C'         -- Prendo solo le richieste completate
         AND r.request_id NOT IN (SELECT request_id FROM XXBCYIN.BCY_SUPPORTO_GARANTE_2));-- non importo le transazioni completate e già importate il giorno precedente
         --ORDER BY r.request_id ASC) ;   ---viene errore

    v_status_code varchar2 (4);

gret_code_exception exception;  

BEGIN


     FOR c in cur_request loop



       insert into XXBCYIN.BCY_SUPPORTO_GARANTE_2 
        values (
        BCY_SUPPORTO_GARANTE_2_S.NEXTVAL,
       'QUERY_MASSIVA',
       (g_applicazione  || c.USER_ID),
        'c.USERNAME',
        null,
        c.request_date,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        g_codice_istituto, --defined before in an other procedure of package
        null,
        null,
        null,
        null,
        null,
        'X',
        null,
        g_tipo_client,  --defined before
        null,
        null,
        null,
        null,
        null,
        v_role_desc,    --defined before
        c.conc_login_id,  --defined before
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        g_applicazione,  --defined before
        null,
        null,
        null,
        null,
        v_status_code,  --defined before
        v_return,         --defined before
        'X' ,       
        null, 
        null,
        c.concurrent_program_name,
        c.request_id,
        c.phase_code ,
        c.status_code,
        sysdate);

   end loop;

      commit;
 

При этой вставке ошибок нет, но таблица остается пустой !?!. Выбор курсора правильный .. вставка содержит правильное количество полей.
Есть идеи?

Комментарии:

1. g_start_date (глобальная переменная, я полагаю) установлена правильно?

2. g_start_date := ’01-jun-2014′ определяется в спецификации пакета

3. Вообще говоря, если это не сбой, синтаксической проблемы нет. Наиболее вероятная причина заключается в том, что курсор не возвращает ни одной строки в этом контексте. Вы могли бы написать raise_application_error(-20000,'ammoQ said so'); после начала цикла, чтобы проверить эту теорию: если генерируется исключение, ваш курсор что-то нашел. Если нет, то либо курсор пуст, либо какой EXCEPTION WHEN OTHERS -то блок проглатывает ваши исключения, возможно, включая исключение, вызванное чем-то с insert инструкцией.

Ответ №1:

Я никогда не слышал о проблеме с Oracle, использующим поля курсора в списке ЗНАЧЕНИЙ, но тогда я не думаю, что когда-либо делал это сам. Попробуйте это:

 dbms_output.put_line( 'Inserting ' || c.username );
insert into XXBCYIN.BCY_SUPPORTO_GARANTE_2 
select
    BCY_SUPPORTO_GARANTE_2_S.NEXTVAL,
    'QUERY_MASSIVA',
    (g_applicazione  || c.USER_ID),
    'c.USERNAME',
    null,
    c.request_date,
    null,    null,    null,    null,    null,    null,    null,    null,
    g_codice_istituto, --defined before in an other procedure of package
    null,    null,    null,    null,    null,    'X',    null,
    g_tipo_client,  --defined before
    null,    null,    null,    null,    null,
    v_role_desc,    --defined before
    c.conc_login_id,  --defined before
    null,    null,    null,    null,    null,    null,    null,
    g_applicazione,  --defined before
    null,    null,    null,    null,
    v_status_code,  --defined before
    v_return,         --defined before
    'X' ,    null,     null,
    c.concurrent_program_name,
    c.request_id,
    c.phase_code ,
    c.status_code,
    sysdate
from dual;
 

Конечно, вы можете переписать вставку, полностью пропустив курсор:

 insert into XXBCYIN.BCY_SUPPORTO_GARANTE_2
select BCY_SUPPORTO_GARANTE_2_S.NEXTVAL,
    'QUERY_MASSIVA',
    (g_applicazione  || c.USER_ID),
    'c.USERNAME',
    null,
    c.request_date,
    etc...
from whatever_table c
where everthing_else_as_in_cursor;
 

Комментарии:

1. Я постоянно использую поля курсора во всех видах операций, включая вставки, поэтому я уверен, что причина не в этом.

2. Если вы так говорите. Но помогло ли какое-либо из моих предложений?

Ответ №2:

Я думаю, вам нужно открыть курсор, а в конце закрыть его. Это означает, что вы должны написать (внутри НАЧАЛЬНОЙ и КОНЕЧНОЙ части) что-то вроде этого:

 OPEN cur_request;
LOOP
   FETCH cur_request INTO v_some_variable;
   EXIT WHEN cur_request%NOTFOUND;
     your_insert_statement;
END LOOP;
CLOSE cur_request;
 

Переменная v_some_variable должна быть объявлена в части DECLARE, а ее тип должен соответствовать типу строки результата вашего оператора select .

Комментарии:

1. Явное открытие и закрытие не требуется, for in цикл, как показано в вопросе, работает так же хорошо.