General
=====================================
Overview:
There is a table, which is source table.
The records from this table should be processed, and inserted into a target table.
Once done, records from source table are deleted.
This Package handles same task in two ways:
convertSdr2CdrCursor
convertSdr2CdrBulk
convertSdr2CdrCursor
The records are selected via regular cursor, and processed one by one.
convertSdr2CdrBulk
The records are selected via BULK COLLECT, and processed one by one.
Since the processing is done one by one, there is no real advantage for using BULK COLLECT.
=====================================
The time to execute in both options
=====================================
convertSdr2CdrCursorDelete 50000 records using regular cursor
Time to Execute: 999(sec), rows deleted: 5000050000/999=50 rows/sec
convertSdr2CdrBulk
Delete 50000 records using BULK COLLECT
Time to Execute: 1249(sec), rows deleted: 60762
60762/1249 = 48 rows/sec
Both options were far superior to not using bind variables.
Without using bind variables, the time was 6 rows/sec.
=====================================
Code
=====================================
CREATE OR REPLACE PACKAGE BODY SDR_2_CDR_CONVERT_ALEC AS
PROCEDURE write_to_log(p_data in varchar2) is
pragma autonomous_transaction;
begin
insert into SGA_W_LOG (procedure_name, data, ts_last_modified) values ('ConvertSdr2Cdr', p_data, sysdate);
commit;
end;
-------------------------------------------------------
-- Process using Regular Cursor
-------------------------------------------------------
cursor SdrCrs(pProductName in varchar2) is
SELECT cdr_id,
outgoing_call_direction
from DEBUG_GEN_W_NEW_SDR_ALEC
where rownum < 50000
and product_name = pProductName
and ((pProductName = 'MOCO' and event_name = 'IDP') OR (pProductName <> 'MOCO'))
for update;
Vsql VARCHAR2(5000);
v_sql_type1 VARCHAR2(5000);
v_sql_type2 VARCHAR2(5000);
v_start_date DATE;
v_end_date DATE;
v_seconds NUMBER;
BEGIN
v_start_date := SYSDATE;
write_to_log('start running convertSdr2CdrCursor procedure at '||TO_CHAR(v_start_date,'YYYYMMDD hh24:mi:ss') );
v_sql_type1 := GenerateCdr(1);
v_sql_type2 := GenerateCdr(2);
-- for each SDR create the mapped CDRs
for SdrRec in SdrCrs(pProductName) loop
begin
Vsql := v_sql_type1;
-- create the insert statement and execute it
Vsql := 'insert into CDR_ALEC select ' || Vsql || ' from DEBUG_GEN_W_NEW_SDR_ALEC where cdr_id = :b1';
EXECUTE IMMEDIATE Vsql USING SdrRec.cdr_id;
-- Generate CDR for Leg2
if SdrRec.outgoing_call_direction is not null then
Vsql :=v_sql_type2;
Vsql := 'insert into CDR_ALEC select ' || Vsql || ' from DEBUG_GEN_W_NEW_SDR_ALEC where cdr_id = :b1';
EXECUTE IMMEDIATE Vsql USING SdrRec.cdr_id;
end if;
delete DEBUG_GEN_W_NEW_SDR_ALEC WHERE CURRENT OF SdrCrs;
EXCEPTION
WHEN OTHERS THEN
write_to_log('Error for CDR_ID: '|| SdrRec.Cdr_Id || ' - ' ||sqlerrm);
UPDATE DEBUG_GEN_W_NEW_SDR_ALEC
SET ROAMING_TYPE ='9'
WHERE CURRENT OF SdrCrs;
END;
END LOOP;
COMMIT;
v_end_date := SYSDATE;
write_to_log('convertSdr2CdrCursor procedure completed at '||TO_CHAR(v_end_date,'YYYYMMDD hh24:mi:ss'));
v_seconds := ROUND((v_end_date - v_start_date)*1440*60);
write_to_log('Time to Execute: '||v_seconds||'(sec)');
end convertSdr2CdrCursor;
-------------------------------------------------------
-- Process using BULK COLLECT
-------------------------------------------------------
PROCEDURE convertSdr2CdrBulk(p_product_name IN VARCHAR2) IS
TYPE sdr_record IS RECORD (
sdr_rowid ROWID,
cdr_id DEBUG_GEN_W_NEW_SDR_ALEC.cdr_id%TYPE,
outgoing_call_direction DEBUG_GEN_W_NEW_SDR_ALEC.outgoing_call_direction%TYPE
);
TYPE sdr_record_tab IS TABLE OF sdr_record;
v_sdr_records sdr_record_tab;
CURSOR sdr_cur IS
SELECT ROWID, cdr_id, outgoing_call_direction
FROM DEBUG_GEN_W_NEW_SDR_ALEC
WHERE 1=1
AND product_name = p_product_name
AND ((p_product_name = 'MOCO' and event_name = 'IDP') OR (p_product_name <> 'MOCO'));
v_sql VARCHAR2(5000);
v_insert_sql VARCHAR2(5000);
v_sql_type1 VARCHAR2(5000);
v_sql_type2 VARCHAR2(5000);
v_outgoingCallDirection SDR_2_CDR_MAPPING_NEW.sdr_column_name%TYPE;
v_start_date DATE;
v_end_date DATE;
v_seconds NUMBER;
v_cdr_id DEBUG_GEN_W_NEW_SDR_ALEC.cdr_id%TYPE;
c_limit NUMBER := 50000;
BEGIN
v_start_date := SYSDATE;
write_to_log('Start running ConvertSdr2CdrBulk procedure at '||TO_CHAR(v_start_date,'YYYYMMDD hh24:mi:ss') );
v_sql_type1 := GenerateCdr(1);
v_sql_type2 := GenerateCdr(2);
SELECT sdr_column_name INTO v_outgoingCallDirection
FROM SDR_2_CDR_MAPPING_NEW
WHERE leg_id = 2
AND cdr_column_name = 'CALL_DIRECTION';
write_to_log('Before Opening Cursor');
OPEN sdr_cur;
--Loop on Cursor
LOOP
BEGIN
FETCH sdr_cur
BULK COLLECT INTO v_sdr_records LIMIT c_limit;
IF sdr_cur%NOTFOUND THEN
write_to_log('No More Data to Fetch from DB');
END IF;
write_to_log('v_sdr_records.COUNT : '||v_sdr_records.COUNT );
write_to_log('Processing Data');
--Loop on the Bulk records
FOR indx IN 1 .. v_sdr_records.COUNT LOOP
BEGIN
-- create the insert statement and execute it
v_sql := v_sql_type1;
v_insert_sql := 'INSERT INTO CDR_ALEC SELECT ' || v_sql || ' FROM DEBUG_GEN_W_NEW_SDR_ALEC WHERE cdr_id = :b1';
v_cdr_id := v_sdr_records(indx).cdr_id;
EXECUTE IMMEDIATE v_insert_sql USING v_cdr_id;
--check whether to create 2nd CDR for outgoing leg
IF v_sdr_records(indx).outgoing_call_direction IS NOT NULL THEN
v_sql := v_sql_type2;
v_insert_sql := 'INSERT INTO CDR_ALEC SELECT ' || v_sql || ' FROM DEBUG_GEN_W_NEW_SDR_ALEC WHERE cdr_id = :b1';
EXECUTE IMMEDIATE v_insert_sql USING v_sdr_records(indx).cdr_id;
END IF;
DELETE DEBUG_GEN_W_NEW_SDR_ALEC WHERE DEBUG_GEN_W_NEW_SDR_ALEC.rowid = v_sdr_records(indx).sdr_rowid;
EXCEPTION
WHEN OTHERS THEN
write_to_log('ConvertSdr2CdrBulk Error for CDR_ID: '|| v_sdr_records(indx).cdr_id || ' Error Details: ' ||SQLERRM);
UPDATE DEBUG_GEN_W_NEW_SDR_ALEC
SET ROAMING_TYPE ='9'
WHERE cdr_id = v_sdr_records(indx).cdr_id;
END;
END LOOP;
EXIT WHEN sdr_cur%NOTFOUND;
EXCEPTION
WHEN OTHERS THEN
write_to_log('Unexpected Error in ConvertSdr2CdrBulk: '||SQLERRM);
END;
END LOOP;
CLOSE sdr_cur;
COMMIT;
v_end_date := SYSDATE;
write_to_log('ConvertSdr2CdrBulk procedure completed at '||TO_CHAR(v_end_date,'YYYYMMDD hh24:mi:ss'));
v_seconds := ROUND((v_end_date - v_start_date)*1440*60);
write_to_log('Time to Execute: '||v_seconds||'(sec)');
END ConvertSdr2CdrBulk;
END SDR_2_CDR_CONVERT_ALEC;
No comments:
Post a Comment