Add invalid remarks for each invalid records inserted into the invalid table in oracle

大城市里の小女人 提交于 2020-05-30 07:48:28

问题


I have a cursor which inserts the valid data into valid table and invalid data into invalid table based on several criteria. Below is my cursor logic for the same.

create or replace PROCEDURE FIP_VAL_INV_DATA AS 
l_state_name r4g_lb.mantainenceboundary_evw.jiostatename%type;
l_maint_zone_code r4g_lb.mantainenceboundary_evw.maintenancezonecode%type;
l_maint_zone_name r4g_lb.mantainenceboundary_evw.maintenancezonename%type;
l_state_code r4g_lb.mantainenceboundary_evw.jiostatecode%type;

begin

  for cur_r in (select rj_span_id, 
                       rj_maintenance_zone_name,
                       rj_maintenance_zone_code,
                       rj_state_name,
                       rj_network_category,
                       rj_network_type,
                       rj_construction_methodology,
                       inventory_status_code,
                       rj_route_name,
                       rj_intracity_link_id,
                       calculated_length 
                      from app_fttx.transmedia@sat 
                      where --rownum < 100 and
                      jumper_flag is null
               )               
  loop 
  
  select max(jiostatename)
      into l_state_name
      from r4g_lb.mantainenceboundary_evw
      where jiostatename = cur_r.rj_state_name
      and rownum = 1;
      
--dbms_output.put_line('test');

      select max(maintenancezonecode), max(maintenancezonename)
      into l_maint_zone_code, l_maint_zone_name
      from r4g_lb.mantainenceboundary_evw
      where maintenancezonecode = cur_r.rj_maintenance_zone_code
      and maintenancezonename = cur_r.rj_maintenance_zone_name
      and rownum = 1;
  
 
   
      if length(cur_r.rj_span_id) =  '21'
          and cur_r.inventory_status_code = 'IPL'
          and regexp_like(cur_r.rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$')
          and NVL(INSTR(cur_r.RJ_INTRACITY_LINK_ID, '_'), 1) > 0 
          and cur_r.rj_maintenance_zone_code = l_maint_zone_code
          and cur_r.rj_maintenance_zone_name = l_maint_zone_name
          and cur_r.rj_state_name = l_state_name  
          
          
    then 
      begin      
       INSERT INTO tbl_fiber_valid_trans_data 
         (span_id, maintenance_zone_name, maintenance_zone_code, r4g_state_name, inventory_status_code, network_category, network_type, construction_methodology, route_name,intracity_link_id, calculated_length, last_updated_by)
          values
         (cur_r.rj_span_id, cur_r.rj_maintenance_zone_name, cur_r.rj_maintenance_zone_code, cur_r.rj_state_name, cur_r.inventory_status_code, cur_r.rj_network_category, cur_r.rj_network_type, cur_r.rj_construction_methodology, cur_r.rj_route_name, cur_r.rj_intracity_link_id, cur_r.calculated_length, 'Test');
      end;      
   
    elsif LENGTH(cur_r.rj_intracity_link_id) > 8 
              AND LENGTH(cur_r.rj_intracity_link_id) < 21
              and cur_r.inventory_status_code = 'IPL'    
             and cur_r.rj_maintenance_zone_code = l_maint_zone_code
             and cur_r.rj_maintenance_zone_name = l_maint_zone_name
            and cur_r.rj_state_name = l_state_name  
   then
    begin
     INSERT INTO tbl_fiber_valid_trans_data 
         (span_id, maintenance_zone_name, maintenance_zone_code, r4g_state_name, inventory_status_code, network_category, network_type, construction_methodology, route_name,intracity_link_id, calculated_length, last_updated_by)
          values
         (cur_r.rj_span_id, cur_r.rj_maintenance_zone_name, cur_r.rj_maintenance_zone_code, cur_r.rj_state_name, cur_r.inventory_status_code, cur_r.rj_network_category, cur_r.rj_network_type, cur_r.rj_construction_methodology, cur_r.rj_route_name, cur_r.rj_intracity_link_id, cur_r.calculated_length, 'Test');
      
    end;
    else begin
        INSERT INTO TBL_FIBER_INVALID_TRANS_DATA 
          (span_id, maintenance_zone_name, maintenance_zone_code, r4g_state_name, inventory_status_code, network_category, network_type, construction_methodology, route_name,intracity_link_id, calculated_length, last_updated_by, remarks)
          values
         (cur_r.rj_span_id, cur_r.rj_maintenance_zone_name, cur_r.rj_maintenance_zone_code, cur_r.rj_state_name, cur_r.inventory_status_code, cur_r.rj_network_category, cur_r.rj_network_type, cur_r.rj_construction_methodology, cur_r.rj_route_name, cur_r.rj_intracity_link_id, cur_r.calculated_length, 'Test', dynamic remarks based upon the error);
         end;        
         
         
    end if;       
  end loop; 
  
END FIP_VAL_INV_DATA;

So now what I want is, If one row is invalid and gets inserted into the invalid table i.e TBL_FIBER_INVALID_TRANS_DATA. I want also to insert the remarks for what reason the record is invalid.

For adding reason, i have several conditions mentioned above like,

if length(cur_r.rj_span_id) = '21' suppose the length is not equal to 21. We can add remarks as The length is not equal to 21 characters.

Like this we can add several remarks in remarks column of invalid table dynamically.

Please suggest how to achieve it.

UPDATE


回答1:


There are several options you may choose. One is to create additional table which logs all errors you find. It has two columns: ID and ERR_CODE. You'd then have to search through source data set and insert rows into that table, e.g.

ERR_CODE = 1 = length not equal to 21

Then:

insert into errors (id, err_code)
  select t.id, 1
  from source_table t
  where length(some_column) <> 21;

It allows you to store multiple errors for the same ID, and it'll be normalized.


Another option is to alter TBL_FIBER_INVALID_TRANS_DATA and add errors varchar2(100); you'd still have to find what's wrong and

  • insert one row per ID per error description (so, multiple rows per ID if it has many errors)
  • insert only one row per ID and concatenate error codes into the newly added column (so if ID contains errors 1, 8 and 12 it would contain e.g. 1/8/12). This is OK if there are only a few errors so you can see what's going on simply by looking at it, but - if there are more errors you capture, it becomes difficult to understand, it is not normalized and you'll have additional problems if you'd want to present all errors found on one ID

If I were you, I'd probably go with option #1 and additional table. Then it is easy to create report for end users (or yourself) by joining TBL_FIBER_INVALID_TRANS_DATA and ERRORS on same ID.




回答2:


For each cursor record, define a variable l_invalid_reason. Perform each validation individually and, if one fails, write the appropriate message into l_invalid_reason.

Then, if l_invalid_reason is null, insert it into the "valid" table. Otherwise, insert into the "invalid" table, passing l_invalid_reason in for the remarks column. Here is an abridged version of your code that does this, with comments.

create or replace PROCEDURE FIP_VAL_INV_DATA AS 

begin
  -- Open your cursor loop
  for cur_r in (select ... ) loop

  declare
    l_invalid_reason VARCHAR2(100);
  begin
    -- Do various select into commands to get extra data needed (e.g. l_state_name, l_maint_zone_code, and l_maint_zone_name
    select max(jiostatename) into l_state_name...
    ...
    ...


    -- Do each validation individually
    -- Notice you are checking for INVALID conditions, not VALID ones, so the
    -- logic is reversed from your posting and you may need to account for possible nulls, 
    -- as in some of the examples below.
    if length(cur_r.rj_span_id) != 21 then
      l_invalid_reason := 'Length is not 21 characters exactly';
    else if nvl(cur_r_inventory_status_code,'XXX') != 'IPL' then
      l_invalid_reason := 'Inventory status code is not IPL';
    else if not regexp_like(cur_r.rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$') then
      l_invalid_reason := 'Span ID does not match accepted format';
    else if .... (additional validations) ...

    end if;

    -- Check to see whether there is an invalid reason
    if l_invalid_reason is null then
      -- insert into good table
    else
      -- insert into invalid table
        INSERT INTO TBL_FIBER_INVALID_TRANS_DATA 
          (span_id, 
           maintenance_zone_name, 
           maintenance_zone_code, 
           ...
           remarks)
          values
         (cur_r.rj_span_id, 
          cur_r.rj_maintenance_zone_name, 
          cur_r.rj_maintenance_zone_code, 
          ...
          l_invalid_reason);  -- put the PL/SQL variable holding the invalid reason into the INSERT statement
    end if;        
  end;       
  end loop; 

END FIP_VAL_INV_DATA;


来源:https://stackoverflow.com/questions/61608789/add-invalid-remarks-for-each-invalid-records-inserted-into-the-invalid-table-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!