После вызова процедуры записи не вставляются в соответствующие таблицы

#oracle #plsql

Вопрос:

 CREATE TABLE STAGING_tab (  E_ID NUMBER(10),  E_NAME VARCHAR2(30),  E_LOC VARCHAR2(30),  VALIDATION_STATUS varchar2(30),  validation_msg varchar2(30),   req_id number(10)  );  insert into staging_tab values(1,'A','AA',null,null,1); insert into staging_tab values(2,'B','BB',null,null,1); insert into staging_tab values(3,'C','CC',null,null,1); insert into staging_tab values(null,'D','DD',null,null,2); insert into staging_tab values(null,'E','EE',null,null,2); insert into staging_tab values(null,'F','GG',null,null,2);  CREATE TABLE tab_ref (  ref_id number(10),  ref_name varchar2(30) );  insert into tab_ref values(1,'aa'); insert into tab_ref values(2,'bb'); insert into tab_ref values(3,'cc'); insert into tab_ref values(4,'dd');  CREATE TABLE tab_ref_2 (  ref_id number(10),  ref_name varchar2(30) );  insert into tab_ref_2 values(1,'ee'); insert into tab_ref_2 values(2,'ff'); insert into tab_ref_2 values(3,'gg'); insert into tab_ref_2 values(4,'hh');  CREATE TABLE SUMMARY_TAB (   TOT_RECORDS NUMBER(10,0),   SUCCESS_RECORDS NUMBER(10,0),   FAILED_RECORDS NUMBER(10,0),  process_status varchar2(30) );  CREATE TABLE TARGET_TAB (   E_ID NUMBER(10,0),   E_NAME VARCHAR2(30),   E_LOC VARCHAR2(30) );  

Хранимая процедура :

 create or replace procedure sp_stage_target(iv_req_id IN sys.OdciNumberList,ov_err_msg OUT varchar2) is  lv_succ_rec number(30);  lv_fail_rec number(30);  lv_count_ref number(10);  lv_count_ref2 number(10);  lv_threshold_cnt number(10);  lv_RejectedCount number(10);  lv_status varchar2(30); begin  lv_succ_rec := 0;  lv_fail_rec := 0;  lv_threshold_cnt := 5;   /*First checking whether data is present in reference table or not.   If data is not present then process should stop*/  select count(1) into lv_count_ref from tab_ref;   select count(1) into lv_count_ref2 from tab_ref_2;   if lv_count_ref = 0 then  ov_err_msg := 'Records are not present in the reference table !!Cannot proceed';   elsif lv_count_ref2 = 0 then  ov_err_msg := 'Records are not present in the reference table !!Cannot proceed';   else   dbms_output.put_line('Data are present into reference tables');   merge into staging_tab d  using (  select 'Fail' as validation_status, t.column_value as req_id  from table(iv_req_id) t  ) s  on (d.req_id = s.req_id)  when matched then  update set  d.validation_status = s.validation_status  , d.validation_msg = case  when e_id is null then 'Id is not present'  else 'Id is longer than expected'  end  where e_id is null OR LENGTH(e_id) gt; 4;  lv_RejectedCount := SQL%ROWCOUNT;  end if; --If rejected count is less than lv_threshold_cnt i.e 5  --then success records will go in target_tab and failed records will go in reject_tab  if lv_RejectedCount lt;= lv_threshold_cnt then  lv_status := 'Success';   dbms_output.put_line('Success');    merge into target_tab t  using (  select e_id, e_name, e_loc  from staging_tab  where validation_status is null and req_id in (select column_value from table(iv_req_id))  ) s  on (t.e_id = s.e_id)  when matched then   update set   t.e_name = s.e_name,  t.e_loc = s.e_loc  when not matched then   insert (t.e_id,t.e_name,t.e_loc)  values (s.e_id,s.e_name,s.e_loc);  lv_succ_rec := SQL%ROWCOUNT;  end if;   insert into reject_tab(e_id, e_name, e_loc, validation_status,validation_msg)  select e_id, e_name, e_loc, validation_status,validation_msg  from staging_tab   where validation_status = 'Fail' and req_id in (select column_value from table(iv_req_id));    lv_fail_rec := SQL%ROWCOUNT;   --In Summary table keeping track of all the records i.e success record, failed records  dbms_output.put_line('Inserting into Summary table');  insert into summary_tab(tot_records, success_records, failed_records, process_status)  values (lv_succ_rec   lv_fail_rec, lv_succ_rec, lv_fail_rec, lv_status);  ov_err_msg := 'Procedure completed succesfully';   commit; end;  

Процедура вызова :

 declare  err_msg varchar2(4000); begin  sp_stage_target(sys.OdciNumberList(1,2),err_msg);  dbms_output.put_line(err_msg); end;  

Когда я вызываю процедуру, я не получаю результатов. В идеале он должен вставлять записи из промежуточной таблицы в target_tab, reject_tab и summary_tab. Но не получаю никаких записей. Кто-нибудь может помочь с этим? Я запрашиваю процедуру вызова только в одном сеансе.

Ответ №1:

Спасибо за тестовый случай; его редко можно увидеть.

Насколько я могу судить, ваша процедура работает. Хотя вы не опубликовали reject_table описание, поэтому я прокомментировал этот фрагмент кода вне процедуры, но … остальное, похоже, в порядке.

 SQLgt; declare  2 err_msg varchar2(4000);  3 begin  4 sp_stage_target(sys.OdciNumberList(1,2),err_msg);  5 dbms_output.put_line(err_msg);  6 end;  7 / Data are present into reference tables Success Inserting into Summary table Procedure completed succesfully  PL/SQL procedure successfully completed.  SQLgt; select * From target_tab;   E_ID E_NAME E_LOC ---------- ---------- ------------------------------  3 C CC  1 A AA  2 B BB  SQLgt; select * from summary_tab;  TOT_RECORDS SUCCESS_RECORDS FAILED_RECORDS PROCESS_STATUS ----------- --------------- -------------- ------------------------------  6 3 3 Success  6 3 3 Success  SQLgt;  

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

1. Точно даже мне интересно, почему это не дает никаких результатов для меня. Существует ли какая-либо ошибка подключения к БД или массив сбора, который не поддерживает?

2. Насколько мне известно, нет. Какой инструмент вы используете?

3. Разработчик Oracle SQL Версии 20.4

4. Так что, когда ты бежишь select * From target_tab; , там ничего нет. Ни когда вы переходите к этой таблице (слева, на панели Навигатор объектов) и просматриваете ее данные (справа)?

5. Да, данных нет, и я просматриваю его данные.

Ответ №2:

Как вы выполняете процедуру вызова? Ваши результаты зависят от DBMS_OUTPUT. Но на самом деле он не генерирует никаких выходных данных, он создает и в буфере, который клиент (здесь ваша вызывающая процедура) может обрабатывать или нет. Если вы запускаете процедуру вызова через SQL*Plus, убедитесь, что у вас есть set serveroutput on перед процедурой. Если через другой api вы можете попробовать dbms_output.enable сразу после начала.

 SET SERVEROUTPUT ON --- THIS  declare  err_msg varchar2(4000); begin  dbms_output.enable; -- OR THIS  sp_stage_target(sys.OdciNumberList(1,2),err_msg);  dbms_output.put_line(err_msg);  end; /  

К сожалению, не все инструменты поддерживают dbms_output.

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

1. Пробовал и с этим тоже. Но все равно не работает. Ничто не обновляется до target_tab, reject_tab и summary_tab