问题
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