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