#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
цикл, как показано в вопросе, работает так же хорошо.