Download - PL/SQL & SQL CODING GUIDELINES – Part 5
![Page 1: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/1.jpg)
PL/SQL & SQL CODING GUIDELINES – PART 5Larry Nung
![Page 2: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/2.jpg)
AGENDAControl Structures
CURSORCASE / IF / DECODE / NVL / NVL2 / COALESCE
ReferenceQ&A
2
![Page 3: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/3.jpg)
CONTROL STRUCTURESCURSOR
![Page 4: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/4.jpg)
31. ALWAYS USE %NOTFOUND INSTEAD OF NOT %FOUND TO CHECK WHETHER A CURSOR WAS
SUCCESSFUL
![Page 5: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/5.jpg)
BADLOOP FETCH c_employees INTO r_employee; EXIT WHEN NOT c_employees%FOUND; ... END LOOP;
![Page 6: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/6.jpg)
GOODLOOP FETCH c_employees INTO r_employee; EXIT WHEN c_employees%NOTFOUND; ... END LOOP;
![Page 7: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/7.jpg)
32. AVOID USING %NOTFOUND DIRECTLY AFTER THE FETCH WHEN WORKING WITH BULK OPERATIONS AND LIMIT CLAUSE. USE
[ARRAY_NAME].COUNT() INSTEAD TO CHECK WHETHER FURTHER FETCHS ARE NEEDED.
![Page 8: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/8.jpg)
BAD-- This example will only show 10 of 14 employees DECLARE TYPE t_employee_type IS TABLE OF emp%ROWTYPE; t_employees t_employee_type; CURSOR c_emp IS SELECT * FROM emp ORDER BY empno; BEGIN OPEN c_emp; <<process_emp>> LOOP FETCH c_emp BULK COLLECT INTO t_employees LIMIT 5; EXIT process_emp WHEN c_emp%NOTFOUND; <<display_emp>> FOR i IN 1..t_employees.COUNT() LOOP sys.dbms_output.put_line(t_employees(i).ename); END LOOP display_emp; END LOOP process_emp; CLOSE c_emp; END;
![Page 9: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/9.jpg)
GOOD-- This example does 4 fetches where 3 were sufficient DECLARE TYPE t_employee_type IS TABLE OF emp%ROWTYPE; t_employees t_employee_type; CURSOR c_emp IS SELECT * FROM emp ORDER BY empno; BEGIN OPEN c_emp; <<process_emp>> LOOP FETCH c_emp BULK COLLECT INTO t_employees LIMIT 5; EXIT WHEN t_employees.COUNT() = 0; <<display_emp>> FOR i IN 1..t_employees.COUNT() LOOP sys.dbms_output.put_line(t_employees(i).ename); END LOOP display_emp; END LOOP process_emp; CLOSE c_emp; END;
![Page 10: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/10.jpg)
GOOD-- This examples does the trick (3 fetches only and process all rows) DECLARE TYPE t_employee_type IS TABLE OF emp%ROWTYPE; t_employees t_employee_type; CURSOR c_emp IS SELECT * FROM emp ORDER BY empno; BEGIN OPEN c_emp; <<process_emp>> LOOP FETCH c_emp BULK COLLECT INTO t_employees LIMIT 5; <<display_emp>> FOR i IN 1..t_employees.COUNT() LOOP sys.dbms_output.put_line(t_employees(i).ename); END LOOP display_emp; EXIT WHEN t_employees.COUNT() = 0 OR c_emp%NOTFOUND; END LOOP process_emp; CLOSE c_emp; END;
![Page 11: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/11.jpg)
33. ALWAYS CLOSE LOCALLY OPENED CURSORS
![Page 12: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/12.jpg)
BADCREATE PROCEDURE not_close_cursor (out_count
OUT INTEGER) AS CURSOR c1 IS SELECT COUNT (*) FROM all_users; BEGIN out_count := 0; OPEN c1; FETCH c1 INTO out_count; END not_close_cursor; ...
![Page 13: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/13.jpg)
GOODCREATE PROCEDURE close_cursor (out_count OUT
INTEGER) AS CURSOR c1 IS SELECT COUNT (*) FROM all_users; BEGIN out_count := 0; OPEN c1; FETCH c1 INTO out_count; CLOSE c1 END close_cursor;
![Page 14: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/14.jpg)
34. AVOID PROCEDURE OR FUNCTION CALLS BETWEEN A SQL OPERATION AND AN IMPLICIT
CURSOR
![Page 15: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/15.jpg)
BADCREATE PROCEDURE remove_emp_and_process (in_id
IN emp.empno%TYPE) AS BEGIN DELETE FROM emp WHERE empno = in_id RETURNING deptno INTO l_deptno; process_department (...); IF SQL%ROWCOUNT > 1 THEN -- Too many rows deleted! Rollback and recover... ROLLBACK; END IF; END remove_emp_and_process;
![Page 16: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/16.jpg)
CONTROL STRUCTURESCASE / IF / DECODE / NVL / NVL2 / COALESCE
![Page 17: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/17.jpg)
35. TRY TO USE CASE RATHER THAN AN IF STATEMENT WITH MULTIPLE ELSIF PATHS
![Page 18: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/18.jpg)
BADIF l_color = 'red' THEN ... ELSIF l_color = 'blue' THEN ... ELSIF l_color = 'black' THEN ...
![Page 19: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/19.jpg)
GOODCASE l_color WHEN 'red' THEN ... WHEN 'blue' THEN ... WHEN 'black' THEN ... END
![Page 20: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/20.jpg)
36. TRY TO USE CASE RATHER THAN DECODE
![Page 21: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/21.jpg)
BADBEGIN SELECT DECODE(dummy, 'A', 1 , 'B', 2 , 'C', 3 , 'D', 4 , 'E', 5 , 'F', 6 , 7) INTO l_result FROM dual; ...
![Page 22: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/22.jpg)
GOODBEGIN l_result := CASE dummy WHEN 'A' THEN 1 WHEN 'B' THEN 2 WHEN 'C' THEN 3 WHEN 'D' THEN 4 WHEN 'E' THEN 5 WHEN 'F' THEN 6 ELSE 7 END; ...
![Page 23: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/23.jpg)
37. ALWAYS USE COALESCE INSTEAD OF NVL, IF PARAMETER 2 OF THE NVL FUNCTION IS A FUNCTION CALL OR A SELECT STATEMENT
![Page 24: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/24.jpg)
BADSELECT NVL(dummy, function_call()) FROM dual;
![Page 25: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/25.jpg)
GOODSELECT COALESCE(dummy, function_call()) FROM dual;
![Page 26: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/26.jpg)
38. ALWAYS USE CASE INSTEAD OF NVL2 IF PARAMETER 2 OR 3 OF NVL2 IS EITHER A FUNCTION CALL OR A SELECT STATEMENT
![Page 27: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/27.jpg)
BADSELECT NVL2(dummy, function_call(),
function_call()) FROM dual;
![Page 28: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/28.jpg)
GOODSELECT CASE WHEN dummy IS NULL THEN
function_call() ELSE function_call()END FROM dual;
![Page 29: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/29.jpg)
REFERENCE29
![Page 30: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/30.jpg)
REFERENCE Trivadis PL/SQL & SQL Coding Guidelines
Version 2.0 http://www.trivadis.com/sites/default/files/downlo
ads/PLSQL_and_SQL_Coding_Guidelines_2_0_HiRes.pdf
30
![Page 31: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/31.jpg)
Q&A31
![Page 32: PL/SQL & SQL CODING GUIDELINES – Part 5](https://reader038.vdocuments.site/reader038/viewer/2022110217/5882268f1a28ab52368b5173/html5/thumbnails/32.jpg)
QUESTION & ANSWER
32