For example, for the following PL/SQL block, it depends on the EXCEPTION condition to update a table. Though I am not an experienced PL/SQL programmer, I am suspicous this could be considered good practice in PL/SQL.
-- PL/SQL block BEGIN FOR bas_rec IN bas_cur LOOP v_my_account_id:=bas_rec.my_account_id; BEGIN SELECT DISTINCT ms.state_id INTO v_state_id FROM my_sch.tab_ms ms WHERE ms.account_id = v_my_account_id AND ms.state_id IS NOT NULL AND ms.svc_node_type_id NOT IN (203,204,206,208,218,402) AND ms.is_pq ='N' AND ms.svc_status_id = 2; EXCEPTION WHEN TOO_MANY_ROWS THEN UPDATE my_sch.conv_2 bas SET bas.to_be_converted_status=v_exclusion_flag, bas.exclusion_reason = v_exclusion_reason_multi, bas.is_processed = v_processed_flag WHERE bas.my_account_id = v_my_account_id; v_is_updated:='Y'; COMMIT; WHEN NO_DATA_FOUND THEN NULL; WHEN OTHERS THEN dbms_output.put_line('Multi State block OTHERS - v_ban:'||sqlerrm ); COMMIT; END; END LOOP; END;
Anyway, I know that " Don't use PL/SQL to Do the Job of SQL". So I translated the above PL/SQL to the following SQL.
-- SQL code UPDATE my_sch.conv_2 bas SET bas.to_be_converted_status='N', bas.exclusion_reason = 'SERVICES IN MULTIPLE STATES', bas.is_processed ='Y' WHERE bas.is_processed is null AND 1 < ( select count( DISTINCT ms.state_id) from my_ord.tab_ms ms WHERE ms.account_id = bas.my_account_id AND ms.state_id IS NOT NULL AND ms.svc_node_type_id NOT IN (203,204,206,208,218,402) AND ms.is_pq ='N' AND ms.svc_status_id = 2 ) ;
I also re-wrote the other part of the script with SQL. In a small scale test, original PL/SQL took 5 min. My SQL code took about 1.5 min. Sadly, developers are more comfortable with their PL/SQL code and are unwilling to do a thoroug test and verification about SQL method. So I will still use their PL/SQL code in the production implementation - just running 5 threads of them to speed up instead of 1 thread previously.
No comments:
Post a Comment