From eb9f8963c4c422f118da83bf48f9bb8c9f299a87 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 13:04:38 +0200 Subject: [PATCH 01/63] fix violations of G-7310, G-8310 --- docs/3-coding-style/coding-style.md | 58 +++++++++++++++-------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/docs/3-coding-style/coding-style.md b/docs/3-coding-style/coding-style.md index bdc73278..dea4e0e1 100644 --- a/docs/3-coding-style/coding-style.md +++ b/docs/3-coding-style/coding-style.md @@ -19,33 +19,37 @@ Rule | Description ### Example ``` sql -create or replace procedure set_salary(in_employee_id in employees.employee_id%type) is - cursor c_employees(p_employee_id in employees.employee_id%type) is - select last_name - ,first_name - ,salary - from employees - where employee_id = p_employee_id - order by last_name - ,first_name; - - r_employee c_employees%rowtype; - l_new_salary employees.salary%type; -begin - open c_employees(p_employee_id => in_employee_id); - fetch c_employees into r_employee; - close c_employees; - - new_salary(in_employee_id => in_employee_id - ,out_salary => l_new_salary); - - -- Check whether salary has changed - if r_employee.salary <> l_new_salary then - update employees - set salary = l_new_salary - where employee_id = in_employee_id; - end if; -end set_salary; +create or replace package body employee_api is + procedure set_salary(in_employee_id in integer) is + co_employee_id constant employees.employee_id%type := in_employee_id; + + cursor c_employees(p_employee_id in employees.employee_id%type) is + select last_name + ,first_name + ,salary + from employees + where employee_id = p_employee_id + order by last_name + ,first_name; + + r_employee c_employees%rowtype; + l_new_salary employees.salary%type; + begin + open c_employees(p_employee_id => co_employee_id); + fetch c_employees into r_employee; + close c_employees; + + new_salary(in_employee_id => in_employee_id + ,out_salary => l_new_salary); + + -- Check whether salary has changed + if r_employee.salary <> l_new_salary then + update employees + set salary = l_new_salary + where employee_id = in_employee_id; + end if; + end set_salary; +end employee_api; ``` ## Code Commenting From 5e150f8ac2716b70fcf09b8f8dd74067e636ed13 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 13:07:53 +0200 Subject: [PATCH 02/63] fix violations of G-3210, G-4385, G-7120, G-8310 --- .../3-transaction-control/g-3320.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md b/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md index 4b387421..c3f67ce5 100644 --- a/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md +++ b/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md @@ -10,9 +10,11 @@ Commit inside a non-cursor loop (other loop types than loops over cursors - see ## Example (bad) ``` sql +declare + co_upper_bound constant integer := 5; + l_counter integer := 0; begin <> - for l_counter in 1..5 loop insert into headers (id,text) values (l_counter,'Number ' || l_counter); @@ -22,6 +24,8 @@ begin connect by level <= 3; commit; + l_counter := l_counter + 1; + exit create_headers when l_counter > co_upper_bound; end loop create_headers; end; / @@ -31,22 +35,24 @@ end; ``` sql declare + co_upper_bound constant integer := 5; procedure create_rows( in_header_id in headers.id%type ) is + co_header_id constant headers.id%type := in_header_id; begin - insert into headers (id,text) values (in_header_id,'Number ' || in_header_id); + insert into headers (id,text) values (in_header_id,'Number ' || co_header_id); insert into lines (header_id,line_no,text) - select in_header_id,rownum,'Line ' || rownum + select co_header_id,rownum,'Line ' || rownum from dual connect by level <= 3; commit; - end; + end create_rows; begin <> - for l_counter in 1..5 + for l_counter in 1..co_upper_bound loop create_rows(l_counter); end loop create_headers; From 2c11dada65abfe07d41012517db1683dd14b6e46 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 13:10:12 +0200 Subject: [PATCH 03/63] fix violations of G-8310 --- .../4-control-structures/1-cursor/g-4130.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/1-cursor/g-4130.md b/docs/4-language-usage/4-control-structures/1-cursor/g-4130.md index cee5a3f2..21a0a770 100644 --- a/docs/4-language-usage/4-control-structures/1-cursor/g-4130.md +++ b/docs/4-language-usage/4-control-structures/1-cursor/g-4130.md @@ -11,15 +11,16 @@ Any cursors left open can consume additional memory space (i.e. SGA) within the ``` sql create or replace package body employee_api as - function department_salary(in_dept_id in departments.department_id%type) + function department_salary(in_dept_id in integer) return number is cursor c_department_salary(p_dept_id in departments.department_id%type) is select sum(salary) as sum_salary from employees where department_id = p_dept_id; r_department_salary c_department_salary%rowtype; + co_dept_id constant departments.department_id%type := in_dept_id; begin - open c_department_salary(p_dept_id => in_dept_id); + open c_department_salary(p_dept_id => co_dept_id); fetch c_department_salary into r_department_salary; return r_department_salary.sum_salary; @@ -39,8 +40,9 @@ create or replace package body employee_api as from employees where department_id = p_dept_id; r_department_salary c_department_salary%rowtype; + co_dept_id constant departments.department_id%type := in_dept_id; begin - open c_department_salary(p_dept_id => in_dept_id); + open c_department_salary(p_dept_id => co_dept_id); fetch c_department_salary into r_department_salary; close c_department_salary; return r_department_salary.sum_salary; From 8860d31866b93f9fbf0afb1dddc832aae5c1bd57 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 13:49:13 +0200 Subject: [PATCH 04/63] fix violations of G-8310 --- .../4-control-structures/1-cursor/g-4140.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/1-cursor/g-4140.md b/docs/4-language-usage/4-control-structures/1-cursor/g-4140.md index 5830b1c7..305bcc7f 100644 --- a/docs/4-language-usage/4-control-structures/1-cursor/g-4140.md +++ b/docs/4-language-usage/4-control-structures/1-cursor/g-4140.md @@ -19,15 +19,17 @@ create or replace package body employee_api as co_one constant simple_integer := 1; procedure process_dept(in_dept_id in departments.department_id%type) is + co_dept_id constant departments.department_id%type := in_dept_id; begin - null; + sys.dbms_output.put_line('do somthing based on ' || co_dept_id); end process_dept; procedure remove_employee(in_employee_id in employees.employee_id%type) is - l_dept_id employees.department_id%type; + co_employee_id constant departments.department_id%type := in_employee_id; + l_dept_id employees.department_id%type; begin delete from employees - where employee_id = in_employee_id + where employee_id = co_employee_id returning department_id into l_dept_id; process_dept(in_dept_id => l_dept_id); @@ -48,16 +50,18 @@ create or replace package body employee_api as co_one constant simple_integer := 1; procedure process_dept(in_dept_id in departments.department_id%type) is + co_dept_id constant departments.department_id%type := in_dept_id; begin - null; + sys.dbms_output.put_line('do somthing based on ' || co_dept_id); end process_dept; procedure remove_employee(in_employee_id in employees.employee_id%type) is + co_employee_id constant departments.department_id%type := in_employee_id; l_dept_id employees.department_id%type; l_deleted_emps simple_integer; begin delete from employees - where employee_id = in_employee_id + where employee_id = co_employee_id returning department_id into l_dept_id; l_deleted_emps := sql%rowcount; From 49fcd38ec1fa8e58aa87c71df3b99c38e6094a82 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 14:03:39 +0200 Subject: [PATCH 05/63] Fix violations of G-4385, G-4370, G-4375, G-8310 --- .../3-flow-control/g-4310.md | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/3-flow-control/g-4310.md b/docs/4-language-usage/4-control-structures/3-flow-control/g-4310.md index c0a06fac..72f6d439 100644 --- a/docs/4-language-usage/4-control-structures/3-flow-control/g-4310.md +++ b/docs/4-language-usage/4-control-structures/3-flow-control/g-4310.md @@ -16,15 +16,16 @@ ``` sql create or replace package body my_package is procedure password_check(in_password in varchar2) is - co_digitarray constant string(10 char) := '0123456789'; - co_lower_bound constant simple_integer := 1; - co_errno constant simple_integer := -20501; - co_errmsg constant string(100 char) := 'Password must contain a digit.'; - l_isdigit boolean := false; + co_password constant dba_users.password%type := in_password; + co_digitarray constant string(10 char) := '0123456789'; + co_lower_bound constant simple_integer := 1; + co_errno constant simple_integer := -20501; + co_errmsg constant string(100 char) := 'Password must contain a digit.'; + l_isdigit boolean := false; l_len_pw pls_integer; l_len_array pls_integer; begin - l_len_pw := length(in_password); + l_len_pw := length(co_password); l_len_array := length(co_digitarray); <> @@ -33,7 +34,7 @@ create or replace package body my_package is <> for j in co_lower_bound..l_len_pw loop - if substr(in_password,j,1) = substr(co_digitarray,i,1) then + if substr(co_password,j,1) = substr(co_digitarray,i,1) then l_isdigit := true; goto check_other_things; end if; @@ -56,15 +57,16 @@ end my_package; ``` sql create or replace package body my_package is procedure password_check(in_password in varchar2) is - co_digitarray constant string(10 char) := '0123456789'; - co_lower_bound constant simple_integer := 1; - co_errno constant simple_integer := -20501; - co_errmsg constant string(100 char) := 'Password must contain a digit.'; - l_isdigit boolean := false; + co_password constant dba_users.password%type := in_password; + co_digitarray constant string(10 char) := '0123456789'; + co_lower_bound constant simple_integer := 1; + co_errno constant simple_integer := -20501; + co_errmsg constant string(100 char) := 'Password must contain a digit.'; + l_isdigit boolean := false; l_len_pw pls_integer; l_len_array pls_integer; begin - l_len_pw := length(in_password); + l_len_pw := length(co_password); l_len_array := length(co_digitarray); <> @@ -73,9 +75,8 @@ create or replace package body my_package is <> for j in co_lower_bound..l_len_pw loop - if substr(in_password,j,1) = substr(co_digitarray,i,1) then + if substr(co_password,j,1) = substr(co_digitarray,i,1) then l_isdigit := true; - exit check_digit; -- early exit condition end if; end loop check_pw_char; end loop check_digit; @@ -96,11 +97,12 @@ end my_package; ``` sql create or replace package body my_package is procedure password_check(in_password in varchar2) is - co_digitpattern constant string(10 char) := '\d'; - co_errno constant simple_integer := -20501; - co_errmsg constant string(100 char) := 'Password must contain a digit.'; + co_password constant dba_users.password%type := in_password; + co_digitpattern constant string(10 char) := '\d'; + co_errno constant simple_integer := -20501; + co_errmsg constant string(100 char) := 'Password must contain a digit.'; begin - if not regexp_like(in_password,co_digitpattern) then + if not regexp_like(co_password,co_digitpattern) then raise_application_error(co_errno,co_errmsg); end if; end password_check; From 4b69512cea864582c2a705d0152d674b2a4da148 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 14:07:56 +0200 Subject: [PATCH 06/63] Fix violations of G-8310 --- docs/4-language-usage/5-exception-handling/g-5060.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/5-exception-handling/g-5060.md b/docs/4-language-usage/5-exception-handling/g-5060.md index 19d7ca1b..4acbd733 100644 --- a/docs/4-language-usage/5-exception-handling/g-5060.md +++ b/docs/4-language-usage/5-exception-handling/g-5060.md @@ -17,12 +17,13 @@ The form that this failure takes does not necessarily need to be an exception. W create or replace package body department_api is function name_by_id(in_id in departments.department_id%type) return departments.department_name%type is + co_id constant departments.department_id%type := in_id; l_department_name departments.department_name%type; begin select department_name into l_department_name from departments - where department_id = in_id; + where department_id = co_id; return l_department_name; end name_by_id; @@ -36,12 +37,13 @@ end department_api; create or replace package body department_api is function name_by_id(in_id in departments.department_id%type) return departments.department_name%type is + co_id constant departments.department_id%type := in_id; l_department_name departments.department_name%type; begin select department_name into l_department_name from departments - where department_id = in_id; + where department_id = co_id; return l_department_name; exception From 40089f7c386fc839260afccf70ab5c275d24adf7 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 14:18:40 +0200 Subject: [PATCH 07/63] Fix violations of G-7110, G-8310 --- .../5-exception-handling/g-5080.md | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/4-language-usage/5-exception-handling/g-5080.md b/docs/4-language-usage/5-exception-handling/g-5080.md index f378dfa7..5b4a107c 100644 --- a/docs/4-language-usage/5-exception-handling/g-5080.md +++ b/docs/4-language-usage/5-exception-handling/g-5080.md @@ -14,12 +14,17 @@ If you use `sqlerrm` or `format_error_stack` to log/display error, you should al ``` sql create or replace package body order_api as procedure discount_and_recalculate( - in_customer_id in customer.id%type - ,in_discount in customer.discount_percentage%type + in_customer_id in integer + ,in_discount in number ) is + co_customer_id constant customer.id%type := in_customer_id; + co_discount constant customer.discount_percentage%type := in_discount; begin - customer_api.apply_discount(in_customer_id,in_discount); - customer_api.in_customer_id(10293847); + customer_api.apply_discount( + in_customer_id => co_customer_id + ,in_discount => co_discount + ); + customer_api.calc(co_customer_id); exception when zero_divide then null; -- ignore @@ -36,12 +41,17 @@ end order_api; ``` sql create or replace package body order_api as procedure discount_and_recalculate( - in_customer_id in customer.id%type - ,in_discount in customer.discount_percentage%type + in_customer_id in integer + ,in_discount in number ) is + co_customer_id constant customer.id%type := in_customer_id; + co_discount constant customer.discount_percentage%type := in_discount; begin - customer_api.apply_discount(in_customer_id,in_discount); - customer_api.in_customer_id(10293847); + customer_api.apply_discount( + in_customer_id => co_customer_id + ,in_discount => co_discount + ); + customer_api.calc(co_customer_id); exception when zero_divide then null; -- ignore From 7db927d53ba81dbfdb5df43f9a255c851d965dcd Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 14:30:16 +0200 Subject: [PATCH 08/63] Fix violoations of G-8310 --- docs/4-language-usage/6-dynamic-sql/g-6020.md | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/docs/4-language-usage/6-dynamic-sql/g-6020.md b/docs/4-language-usage/6-dynamic-sql/g-6020.md index dceb8d46..e9da6941 100644 --- a/docs/4-language-usage/6-dynamic-sql/g-6020.md +++ b/docs/4-language-usage/6-dynamic-sql/g-6020.md @@ -14,17 +14,21 @@ You should use the `returning into` clause for values returned from a DML operat ``` sql create or replace package body employee_api is - procedure upd_salary(in_employee_id in employees.employee_id%type - ,in_increase_pct in types_up.percentage - ,out_new_salary out employees.salary%type) + procedure upd_salary( + in_employee_id in employees.employee_id%type + ,in_increase_pct in types_up.percentage + ,out_new_salary out employees.salary%type + ) is - co_sql_stmt constant types_up.big_string_type := ' + co_employee_id constant employees.employee_id%type := in_employee_id; + co_increase_pct constant types_up.percentage := in_increase_pct; + co_sql_stmt constant types_up.big_string_type := ' update employees set salary = salary + (salary / 100 * :1) where employee_id = :2 returning salary into :3'; begin execute immediate co_sql_stmt - using in_increase_pct,in_employee_id,out out_new_salary; + using co_increase_pct,co_employee_id,out out_new_salary; end upd_salary; end employee_api; / @@ -34,17 +38,21 @@ end employee_api; ``` sql create or replace package body employee_api is - procedure upd_salary(in_employee_id in employees.employee_id%type - ,in_increase_pct in types_up.percentage - ,out_new_salary out employees.salary%type) + procedure upd_salary( + in_employee_id in employees.employee_id%type + ,in_increase_pct in types_up.percentage + ,out_new_salary out employees.salary%type + ) is - co_sql_stmt constant types_up.big_string_type := - 'update employees set salary = salary + (salary / 100 * :1) + co_employee_id constant employees.employee_id%type := in_employee_id; + co_increase_pct constant types_up.percentage := in_increase_pct; + co_sql_stmt constant types_up.big_string_type := ' + update employees set salary = salary + (salary / 100 * :1) where employee_id = :2 returning salary into :3'; begin execute immediate co_sql_stmt - using in_increase_pct,in_employee_id + using co_increase_pct,co_employee_id returning into out_new_salary; end upd_salary; end employee_api; From 9af7e086bfff1bdf5158b268eb84a9772efa1430 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 15:02:41 +0200 Subject: [PATCH 09/63] Fix violations of G-8310 --- .../7-stored-objects/1-general/g-7120.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7120.md b/docs/4-language-usage/7-stored-objects/1-general/g-7120.md index aabcbccc..9c15c31c 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7120.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7120.md @@ -11,14 +11,15 @@ It's a good alternative for comments to indicate the end of program units, espec ``` sql create or replace package body employee_api is - function employee_by_id(in_employee_id in employees.employee_id%type) + function employee_by_id(in_employee_id in integer) return employees%rowtype is - r_employee employees%rowtype; + co_employee_id constant employees.employee_id%type := in_employee_id; + r_employee employees%rowtype; begin select * into r_employee from employees - where employee_id = in_employee_id; + where employee_id = co_employee_id; return r_employee; exception @@ -35,14 +36,15 @@ end; ``` sql create or replace package body employee_api is - function employee_by_id(in_employee_id in employees.employee_id%type) + function employee_by_id(in_employee_id in integer) return employees%rowtype is - r_employee employees%rowtype; + co_employee_id constant employees.employee_id%type := in_employee_id; + r_employee employees%rowtype; begin select * into r_employee from employees - where employee_id = in_employee_id; + where employee_id = co_employee_id; return r_employee; exception From fc03cfb962ca8d4d841d097c69b7d0329968c425 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 15:04:59 +0200 Subject: [PATCH 10/63] Fix violations of G-8310 --- .../7-stored-objects/1-general/g-7125.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7125.md b/docs/4-language-usage/7-stored-objects/1-general/g-7125.md index b9c432d0..37a4931b 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7125.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7125.md @@ -11,14 +11,15 @@ Using `create` alone makes your scripts give an error if the program unit alread ``` sql create package body employee_api is - function employee_by_id(in_employee_id in employees.employee_id%type) + function employee_by_id(in_employee_id in integer) return employees%rowtype is - r_employee employees%rowtype; + co_employee_id constant employees.employee_id%type := in_employee_id; + r_employee employees%rowtype; begin select * into r_employee from employees - where employee_id = in_employee_id; + where employee_id = co_employee_id; return r_employee; exception @@ -35,14 +36,15 @@ end employee_api; ``` sql create or replace package body employee_api is - function employee_by_id(in_employee_id in employees.employee_id%type) + function employee_by_id(in_employee_id in integer) return employees%rowtype is - r_employee employees%rowtype; + co_employee_id constant employees.employee_id%type := in_employee_id; + r_employee employees%rowtype; begin select * into r_employee from employees - where employee_id = in_employee_id; + where employee_id = co_employee_id; return r_employee; exception From caf9502bf8f8b8c911ec6192cccacadbf7f8c437 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 15:17:56 +0200 Subject: [PATCH 11/63] Fix violations of G-8310 --- .../7-stored-objects/1-general/g-7130.md | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7130.md b/docs/4-language-usage/7-stored-objects/1-general/g-7130.md index e4eb5874..aa280e0c 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7130.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7130.md @@ -13,8 +13,9 @@ This external dependency is hidden, and may cause problems in the future. You sh ``` sql create or replace package body employee_api is - procedure calc_salary(in_employee_id in employees.employee_id%type) is - r_emp employees%rowtype; + procedure calc_salary(in_employee_id in integer) is + co_employee_id constant employees.employee_id%type := in_employee_id; + r_emp employees%rowtype; function commission return number is l_commission employees.salary%type := 0; @@ -29,7 +30,7 @@ create or replace package body employee_api is select * into r_emp from employees - where employee_id = in_employee_id; + where employee_id = co_employee_id; sys.dbms_output.put_line(r_emp.salary + commission()); exception @@ -46,16 +47,21 @@ end employee_api; ``` sql create or replace package body employee_api is - procedure calc_salary(in_employee_id in employees.employee_id%type) is - r_emp employees%rowtype; + procedure calc_salary(in_employee_id in integer) is + co_employee_id constant employees.employee_id%type := in_employee_id; + r_emp employees%rowtype; - function commission(in_salary in employees.salary%type - ,in_comm_pct in employees.commission_pct%type) + function commission( + in_salary in number + ,in_comm_pct in number + ) return number is - l_commission employees.salary%type := 0; + co_salary constant employees.salary%type := in_salary; + co_comm_pct constant employees.commission_pct%type := in_comm_pct; + l_commission employees.salary%type := 0; begin if in_comm_pct is not null then - l_commission := in_salary * in_comm_pct; + l_commission := co_salary * co_comm_pct; end if; return l_commission; @@ -64,7 +70,7 @@ create or replace package body employee_api is select * into r_emp from employees - where employee_id = in_employee_id; + where employee_id = co_employee_id; sys.dbms_output.put_line( r_emp.salary + commission(in_salary => r_emp.salary From 31f7f8a93f3adae36185d91b71ba1b29be520277 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 15:39:19 +0200 Subject: [PATCH 12/63] Fix violations of G-8310 --- .../7-stored-objects/1-general/g-7150.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7150.md b/docs/4-language-usage/7-stored-objects/1-general/g-7150.md index 20a7c025..b257a36a 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7150.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7150.md @@ -11,9 +11,12 @@ You should go through your programs and remove any parameter that is no longer u ``` sql create or replace package body department_api is - function name_by_id(in_department_id in departments.department_id%type - ,in_manager_id in departments.manager_id%type) + function name_by_id( + in_department_id in integer + ,in_manager in employees%rowtype + ) return departments.department_name%type is + co_department_id constant departments.department_id%type := in_department_id; l_department_name departments.department_name%type; begin <> @@ -21,7 +24,7 @@ create or replace package body department_api is select department_name into l_department_name from departments - where department_id = in_department_id; + where department_id = co_department_id; exception when no_data_found or too_many_rows then l_department_name := null; @@ -37,8 +40,11 @@ end department_api; ``` sql create or replace package body department_api is - function name_by_id(in_department_id in departments.department_id%type) + function name_by_id( + in_department_id in integer + ) return departments.department_name%type is + co_department_id constant departments.department_id%type := in_department_id; l_department_name departments.department_name%type; begin <> @@ -46,7 +52,7 @@ create or replace package body department_api is select department_name into l_department_name from departments - where department_id = in_department_id; + where department_id = co_department_id; exception when no_data_found or too_many_rows then l_department_name := null; From 932daf7a192e9109b94920ba022d469f6d0481bf Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 16:28:55 +0200 Subject: [PATCH 13/63] Fix violations of G-1050 --- .../3-transaction-control/g-3320.md | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md b/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md index c3f67ce5..213deff0 100644 --- a/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md +++ b/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md @@ -11,17 +11,30 @@ Commit inside a non-cursor loop (other loop types than loops over cursors - see ``` sql declare - co_upper_bound constant integer := 5; - l_counter integer := 0; + co_upper_bound constant integer := 5; + co_max_level constant integer := 3; + co_number constant types_up.short_string := 'Number'; + co_line constant types_up.short_string := 'Line'; + co_space constant types_up.short_string := ' '; + l_counter integer := 0; begin <> loop - insert into headers (id,text) values (l_counter,'Number ' || l_counter); + insert into headers (id,text) + values ( + l_counter,co_number + || co_space + || l_counter + ); insert into lines (header_id,line_no,text) - select l_counter,rownum,'Line ' || rownum + select l_counter + ,rownum + ,co_line + || co_space + || rownum from dual - connect by level <= 3; + connect by level <= co_max_level; commit; l_counter := l_counter + 1; From 588b17d9a850f3ac43ac82ac2e9320c4766746fa Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 16:33:42 +0200 Subject: [PATCH 14/63] Fix violations of G-1050 --- .../4-control-structures/1-cursor/g-4140.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/1-cursor/g-4140.md b/docs/4-language-usage/4-control-structures/1-cursor/g-4140.md index 305bcc7f..c0c8f2c0 100644 --- a/docs/4-language-usage/4-control-structures/1-cursor/g-4140.md +++ b/docs/4-language-usage/4-control-structures/1-cursor/g-4140.md @@ -17,11 +17,12 @@ In the following example, a procedure call is inserted between the `delete` stat ``` sql create or replace package body employee_api as co_one constant simple_integer := 1; + co_msg constant types_up.text := 'Do something based on '; procedure process_dept(in_dept_id in departments.department_id%type) is co_dept_id constant departments.department_id%type := in_dept_id; begin - sys.dbms_output.put_line('do somthing based on ' || co_dept_id); + sys.dbms_output.put_line(co_msg || co_dept_id); end process_dept; procedure remove_employee(in_employee_id in employees.employee_id%type) is @@ -48,11 +49,12 @@ end employee_api; ``` sql create or replace package body employee_api as co_one constant simple_integer := 1; + co_msg constant types_up.text := 'Do something based on '; procedure process_dept(in_dept_id in departments.department_id%type) is co_dept_id constant departments.department_id%type := in_dept_id; begin - sys.dbms_output.put_line('do somthing based on ' || co_dept_id); + sys.dbms_output.put_line(co_msg || co_dept_id); end process_dept; procedure remove_employee(in_employee_id in employees.employee_id%type) is From 5927f4a810ef6f08dd1c6a6ed47be95be31392f1 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 16:40:46 +0200 Subject: [PATCH 15/63] Fix violations of G-1050 --- .../3-transaction-control/g-3320.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md b/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md index 213deff0..ddf7f588 100644 --- a/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md +++ b/docs/4-language-usage/3-dml-and-sql/3-transaction-control/g-3320.md @@ -48,18 +48,29 @@ end; ``` sql declare - co_upper_bound constant integer := 5; + co_upper_bound constant integer := 5; + co_max_level constant integer := 3; + co_number constant types_up.short_string := 'Number'; + co_line constant types_up.short_string := 'Line'; + co_space constant types_up.short_string := ' '; procedure create_rows( in_header_id in headers.id%type ) is co_header_id constant headers.id%type := in_header_id; begin - insert into headers (id,text) values (in_header_id,'Number ' || co_header_id); + insert into headers (id,text) + values (in_header_id,co_number + || co_space + || co_header_id); insert into lines (header_id,line_no,text) - select co_header_id,rownum,'Line ' || rownum + select co_header_id + ,rownum + ,co_line + || co_space + || rownum from dual - connect by level <= 3; + connect by level <= co_max_level; commit; end create_rows; From 9e113abd89b2d93bd945d6f750e53772d411aa30 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 16:46:17 +0200 Subject: [PATCH 16/63] Fix violations of G-7460 --- docs/4-language-usage/4-control-structures/1-cursor/g-4130.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/1-cursor/g-4130.md b/docs/4-language-usage/4-control-structures/1-cursor/g-4130.md index 21a0a770..624a36db 100644 --- a/docs/4-language-usage/4-control-structures/1-cursor/g-4130.md +++ b/docs/4-language-usage/4-control-structures/1-cursor/g-4130.md @@ -11,7 +11,7 @@ Any cursors left open can consume additional memory space (i.e. SGA) within the ``` sql create or replace package body employee_api as - function department_salary(in_dept_id in integer) + function department_salary(in_dept_id in integer) -- NOSONAR: non-deterministic return number is cursor c_department_salary(p_dept_id in departments.department_id%type) is select sum(salary) as sum_salary @@ -33,7 +33,7 @@ end employee_api; ``` sql create or replace package body employee_api as - function department_salary(in_dept_id in departments.department_id%type) + function department_salary(in_dept_id in integer) -- NOSONAR: non-deterministic return number is cursor c_department_salary(p_dept_id in departments.department_id%type) is select sum(salary) as sum_salary From a9b615e9afeb2db94aa76aa10afcb7369a7808b6 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 16:53:15 +0200 Subject: [PATCH 17/63] Fix violations of G-7460 --- docs/4-language-usage/7-stored-objects/1-general/g-7120.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7120.md b/docs/4-language-usage/7-stored-objects/1-general/g-7120.md index 9c15c31c..a51a9c5f 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7120.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7120.md @@ -11,7 +11,8 @@ It's a good alternative for comments to indicate the end of program units, espec ``` sql create or replace package body employee_api is - function employee_by_id(in_employee_id in integer) + function -- NOSONAR: non-deterministic + employee_by_id(in_employee_id in integer) return employees%rowtype is co_employee_id constant employees.employee_id%type := in_employee_id; r_employee employees%rowtype; @@ -36,7 +37,7 @@ end; ``` sql create or replace package body employee_api is - function employee_by_id(in_employee_id in integer) + function employee_by_id(in_employee_id in integer) -- NOSONAR: non-deterministic return employees%rowtype is co_employee_id constant employees.employee_id%type := in_employee_id; r_employee employees%rowtype; From 4d7d2c6eb8d4b55b91f43bd62a735d2e6494d207 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 16:56:25 +0200 Subject: [PATCH 18/63] Fix violations of G-7460 --- docs/4-language-usage/7-stored-objects/1-general/g-7125.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7125.md b/docs/4-language-usage/7-stored-objects/1-general/g-7125.md index 37a4931b..a257e0c7 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7125.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7125.md @@ -11,7 +11,7 @@ Using `create` alone makes your scripts give an error if the program unit alread ``` sql create package body employee_api is - function employee_by_id(in_employee_id in integer) + function employee_by_id(in_employee_id in integer) -- NOSONAR: non-deterministic return employees%rowtype is co_employee_id constant employees.employee_id%type := in_employee_id; r_employee employees%rowtype; @@ -36,7 +36,7 @@ end employee_api; ``` sql create or replace package body employee_api is - function employee_by_id(in_employee_id in integer) + function employee_by_id(in_employee_id in integer) -- NOSONAR: non-deterministic return employees%rowtype is co_employee_id constant employees.employee_id%type := in_employee_id; r_employee employees%rowtype; From 7d76702d0d2abeea2f0289fee1612cc3ac967758 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 16:59:57 +0200 Subject: [PATCH 19/63] Fix violations of G-7460 --- docs/4-language-usage/7-stored-objects/1-general/g-7130.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7130.md b/docs/4-language-usage/7-stored-objects/1-general/g-7130.md index aa280e0c..b119e783 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7130.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7130.md @@ -17,7 +17,7 @@ create or replace package body employee_api is co_employee_id constant employees.employee_id%type := in_employee_id; r_emp employees%rowtype; - function commission return number is + function commission return number is -- NOSONAR: non-deterministic l_commission employees.salary%type := 0; begin if r_emp.commission_pct is not null then @@ -55,7 +55,9 @@ create or replace package body employee_api is in_salary in number ,in_comm_pct in number ) - return number is + return number + deterministic + is co_salary constant employees.salary%type := in_salary; co_comm_pct constant employees.commission_pct%type := in_comm_pct; l_commission employees.salary%type := 0; From 8d20e26124604f9a559bf5922682e7920b4b197c Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 17:01:30 +0200 Subject: [PATCH 20/63] Fix violations of G-7460 --- docs/4-language-usage/7-stored-objects/1-general/g-7150.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7150.md b/docs/4-language-usage/7-stored-objects/1-general/g-7150.md index b257a36a..e8efaa62 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7150.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7150.md @@ -11,7 +11,7 @@ You should go through your programs and remove any parameter that is no longer u ``` sql create or replace package body department_api is - function name_by_id( + function name_by_id( -- NOSONAR: non-deterministic in_department_id in integer ,in_manager in employees%rowtype ) @@ -40,7 +40,7 @@ end department_api; ``` sql create or replace package body department_api is - function name_by_id( + function name_by_id( -- NOSONAR: non-deterministic in_department_id in integer ) return departments.department_name%type is From c5ec491a3cf2bd26c40e3c5e3e29afaf1febbdca Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 17:12:25 +0200 Subject: [PATCH 21/63] do not report lines with NOSONAR marker --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4165940f..d0c124ab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: unzip tvdcc-$COP.zip -d . wget -P tvdcc-$COP/plugin/ https://github.com/Trivadis/plsql-cop-validators/releases/download/v$VALIDATOR/sonar-plsql-cop-custom-validators-plugin-$VALIDATOR.jar echo $TVDCC_LIC | base64 -d > tvdcc-$COP/tvdcc.lic - tvdcc-$COP/tvdcc.sh path=docs skip=none html=false excel=false validator=com.trivadis.tvdcc.validators.TrivadisGuidelines3Plus + tvdcc-$COP/tvdcc.sh path=docs skip=0 html=false excel=false validator=com.trivadis.tvdcc.validators.TrivadisGuidelines3Plus env: TVDCC_LIC: ${{ secrets.TVDCC_LIC }} - name: SonarCloud Scan From d96e72433c9ade61971103b8f31eaa8e1989f39a Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 21 Jul 2023 17:32:37 +0200 Subject: [PATCH 22/63] Fix violations of G-1050, G-4320, G-4390, G-4395 --- .../5-complexity-analysis/complexity-analysis.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/5-complexity-analysis/complexity-analysis.md b/docs/5-complexity-analysis/complexity-analysis.md index 70e469b8..72d10e20 100644 --- a/docs/5-complexity-analysis/complexity-analysis.md +++ b/docs/5-complexity-analysis/complexity-analysis.md @@ -55,17 +55,23 @@ where Take, for example, a control flow graph of a simple program. The program begins executing at the red node, then enters a loop (group of three nodes immediately below the red node). On exiting the loop, there is a conditional statement (group below the loop), and finally the program exits at the blue node. For this graph, $E = 9$, $N = 8$ and $P = 1$, so the cyclomatic complexity of the program is $3$.

``` sql +declare + co_upper_bound constant integer := 3; + co_msg constant user_objects.object_name%type := 'in loop '; + co_yes constant user_objects.object_name%type := 'yes'; + co_end constant user_objects.object_name%type := 'end'; begin - for i in 1..3 + <> + for i in 1..co_upper_bound loop - sys.dbms_output.put_line('in loop'); - end loop; + sys.dbms_output.put_line(co_msg || i); + end loop print_in_loop; -- if 1 = 1 then - sys.dbms_output.put_line('yes'); + sys.dbms_output.put_line(co_yes); end if; -- - sys.dbms_output.put_line('end'); + sys.dbms_output.put_line(co_end); end; / ``` From 0f0e1c1a754170680a27b4efd274469488f4294a Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 10:10:32 +0200 Subject: [PATCH 23/63] Fix violations of G-4365 --- docs/4-language-usage/1-general/g-1020.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/1-general/g-1020.md b/docs/4-language-usage/1-general/g-1020.md index 55b05e98..9304972a 100644 --- a/docs/4-language-usage/1-general/g-1020.md +++ b/docs/4-language-usage/1-general/g-1020.md @@ -38,7 +38,7 @@ begin <> loop - exit basic_loop; + exit basic_loop when true; end loop; <> @@ -78,7 +78,7 @@ begin <> loop - exit basic_loop; + exit basic_loop when true; end loop basic_loop; <> From f9a9e89b4cb2da8a03ca5ce8beaa8053ff2430af Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 10:58:46 +0200 Subject: [PATCH 24/63] Fix violations of G-4365, explain violations of G-1050 --- docs/4-language-usage/1-general/g-1040.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/4-language-usage/1-general/g-1040.md b/docs/4-language-usage/1-general/g-1040.md index cd83ba99..bca2fbe4 100644 --- a/docs/4-language-usage/1-general/g-1040.md +++ b/docs/4-language-usage/1-general/g-1040.md @@ -13,7 +13,7 @@ Any part of your code, which is no longer used or cannot be reached, should be e declare co_dept_purchasing constant departments.department_id%type := 30; begin - if 2 = 3 then + if 2 = 3 then -- G-1050 violated, dead code detection works with literals only null; -- some dead code here end if; @@ -21,14 +21,14 @@ begin <> loop - exit my_loop; + exit my_loop when true; null; -- some dead code here end loop my_loop; null; -- some other enabled code here case - when 1 = 1 and 'x' = 'y' then + when 1 = 1 and 'x' = 'y' then -- G-1050 violated, dead code detection works with literals only null; -- some dead code here else null; -- some further enabled code here @@ -40,7 +40,7 @@ begin from employees where department_id = co_dept_purchasing or commission_pct is not null - and 5 = 6 + and 5 = 6 -- G-1050 violated, dead code detection works with literals only ) -- "or commission_pct is not null" is dead code loop From 4922137052cfc5a1bac59dfd2c57f3caed9139ec Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 10:59:10 +0200 Subject: [PATCH 25/63] add tvdcc_report.json to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 75677133..888964f3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ /pdf /docs/9-appendix/PLSQL-and-SQL-Coding-Guidelines.pdf +# Files generated by tvdcc +/tvdcc_report.json + # Distribution files /dist /mkdocs_material.egg-info From 2ee500c6cffd8eec55450fbbad363836622e93a6 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 11:07:13 +0200 Subject: [PATCH 26/63] Fix violations of G-1050 --- docs/4-language-usage/1-general/g-1080.md | 40 ++++++++++++++--------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/docs/4-language-usage/1-general/g-1080.md b/docs/4-language-usage/1-general/g-1080.md index bf7256a3..3013c9b0 100644 --- a/docs/4-language-usage/1-general/g-1080.md +++ b/docs/4-language-usage/1-general/g-1080.md @@ -12,24 +12,34 @@ This rule ignores operators `+`, `*` and `||`, and expressions: `1=1`, `1<>1`, ` ## Example (bad) ``` sql -select emp.first_name - ,emp.last_name - ,emp.salary - ,emp.hire_date - from employees emp - where emp.salary > 3000 - or emp.salary > 3000 - order by emp.last_name,emp.first_name; +declare + co_max_salary constant emp.salary%type := 3000; +begin + select emp.first_name + ,emp.last_name + ,emp.salary + ,emp.hire_date + from employees emp + where emp.salary > co_max_salary + or emp.salary > co_max_salary + order by emp.last_name,emp.first_name; +end; +/ ``` ## Example (good) ``` sql -select emp.first_name - ,emp.last_name - ,emp.salary - ,emp.hire_date - from employees emp - where emp.salary > 3000 - order by emp.last_name,emp.first_name; +declare + co_max_salary constant emp.salary%type := 3000; +begin + select emp.first_name + ,emp.last_name + ,emp.salary + ,emp.hire_date + from employees emp + where emp.salary > co_max_salary + order by emp.last_name,emp.first_name; +end; +/ ``` \ No newline at end of file From 75759533f00a7ca25786404e0cd8d2a0f5ce7751 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 11:42:47 +0200 Subject: [PATCH 27/63] Fix violations of G-2135, explain G-9102, G-9114, G-9113 --- .../2-variables-and-types/1-general/g-2180.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/1-general/g-2180.md b/docs/4-language-usage/2-variables-and-types/1-general/g-2180.md index 873ba4da..58e78e9a 100644 --- a/docs/4-language-usage/2-variables-and-types/1-general/g-2180.md +++ b/docs/4-language-usage/2-variables-and-types/1-general/g-2180.md @@ -11,11 +11,12 @@ Quoted identifiers make your code hard to read and maintain. ``` sql declare - "sal+comm" integer; - "my constant" constant integer := 1; - "my exception" exception; + "sal+comm" integer; -- violates also naming conventions (G-9102) + "my constant" constant integer := 1; -- violates also naming conventions (G-9114) + "my exception" exception; -- violates also naming conventsion (G-9113) begin "sal+comm" := "my constant"; + do_something("sal+comm"); exception when "my exception" then null; @@ -32,6 +33,7 @@ declare e_my_exception exception; begin l_sal_comm := co_my_constant; + do_something(l_sal_comm); exception when e_my_exception then null; From 8a6210c0bfdc74327fe4c5af701e70fa8c70430f Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 11:44:04 +0200 Subject: [PATCH 28/63] Fx violations of G-2130, G-1050 --- .../2-variables-and-types/1-general/g-2135.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/1-general/g-2135.md b/docs/4-language-usage/2-variables-and-types/1-general/g-2135.md index ca9892a3..c9a82a34 100644 --- a/docs/4-language-usage/2-variables-and-types/1-general/g-2135.md +++ b/docs/4-language-usage/2-variables-and-types/1-general/g-2135.md @@ -13,15 +13,16 @@ Expending resources calculating and assigning values to a local variable and nev create or replace package body my_package is procedure my_proc is co_employee_id constant employees.employee_id%type := 1042; + co_hello constant type_up.text := 'Hello, '; l_last_name employees.last_name%type; - l_message varchar2(100 char); + l_message types_up.text; begin select emp.last_name into l_last_name from employees emp where emp.employee_id = co_employee_id; - l_message := 'Hello, ' || l_last_name; + l_message := co_hello || l_last_name; exception when no_data_found then null; -- handle_no_data_found; @@ -38,15 +39,16 @@ end my_package; create or replace package body my_package is procedure my_proc is co_employee_id constant employees.employee_id%type := 1042; + co_hello constant type_up.text := 'Hello, '; l_last_name employees.last_name%type; - l_message varchar2(100 char); + l_message types_up.text; begin select emp.last_name into l_last_name from employees emp where emp.employee_id = co_employee_id; - l_message := 'Hello, ' || l_last_name; + l_message := co_hello || l_last_name; message_api.send_message(l_message); exception From 5cb21e793100ba0bed4964803d6f6fddc4e57c28 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 11:46:11 +0200 Subject: [PATCH 29/63] Fix violations of G-2135, G-1050 --- .../2-variables-and-types/1-general/g-2145.md | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/1-general/g-2145.md b/docs/4-language-usage/2-variables-and-types/1-general/g-2145.md index e5f24eaa..5dca2b3e 100644 --- a/docs/4-language-usage/2-variables-and-types/1-general/g-2145.md +++ b/docs/4-language-usage/2-variables-and-types/1-general/g-2145.md @@ -11,12 +11,15 @@ There is no reason to assign a variable to itself. It is either a redundant stat ``` sql declare - l_function_result pls_integer; - l_parallel_degree pls_integer; + co_parallel_degree constant types_up.name%type := 'parallel_degree'; + l_function_result pls_integer; + l_parallel_degree pls_integer; begin - l_function_result := maintenance.get_config('parallel_degree'); - l_parallel_degree := l_parallel_degree; - do_something(l_parallel_degree); + l_function_result := maintenance.get_config(co_parallel_degree); + if l_function_result is not null then + l_parallel_degree := l_parallel_degree; + do_something(l_parallel_degree); + end if; end; / ``` @@ -25,12 +28,15 @@ end; ``` sql declare - l_function_result pls_integer; - l_parallel_degree pls_integer; + co_parallel_degree constant types_up.name%type := 'parallel_degree'; + l_function_result pls_integer; + l_parallel_degree pls_integer; begin - l_function_result := maintenance.get_config('parallel_degree'); - l_parallel_degree := l_function_result; - do_something(l_parallel_degree); + l_function_result := maintenance.get_config(co_parallel_degree); + if l_function_result is not null then + l_parallel_degree := l_function_result; + do_something(l_parallel_degree); + end if; end; / ``` \ No newline at end of file From 1f35389b5164ea34c4b296ab14d86cee73d3bddc Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 11:49:37 +0200 Subject: [PATCH 30/63] bump version of db* CODECOP CLI, validator --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d0c124ab..6512debf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,8 +18,8 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: db* CODECOP Issues run: | - export COP=4.3.0 - export VALIDATOR=4.3.0 + export COP=4.3.1 + export VALIDATOR=4.3.1 wget https://github.com/Trivadis/plsql-cop-cli/releases/download/v$COP/tvdcc-$COP.zip unzip tvdcc-$COP.zip -d . wget -P tvdcc-$COP/plugin/ https://github.com/Trivadis/plsql-cop-validators/releases/download/v$VALIDATOR/sonar-plsql-cop-custom-validators-plugin-$VALIDATOR.jar From 305ca21816a5ee282a884f8bd2f7e7607bc39133 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 12:02:41 +0200 Subject: [PATCH 31/63] Fix violations of G-2135, explain G-9114, G-9113 --- .../2-variables-and-types/1-general/g-2185.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/1-general/g-2185.md b/docs/4-language-usage/2-variables-and-types/1-general/g-2185.md index 3e22f7bf..7bb3dca2 100644 --- a/docs/4-language-usage/2-variables-and-types/1-general/g-2185.md +++ b/docs/4-language-usage/2-variables-and-types/1-general/g-2185.md @@ -12,10 +12,11 @@ You should ensure that the name you have chosen well defines its purpose and usa ``` sql declare i integer; - c constant integer := 1; - e exception; + c constant integer := 1; -- violates also naming conventions (G-9114) + e exception; -- violates also naming conventions (G-9113) begin i := c; + do_something(i); exception when e then null; @@ -32,6 +33,7 @@ declare e_my_exception exception; begin l_sal_comm := co_my_constant; + do_something(l_sal_comm); exception when e_my_exception then null; From be9c1519ef0492d49d283e04ca7eca0cac722c76 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 12:15:59 +0200 Subject: [PATCH 32/63] fix violations of G-7460, G-2130 by using a different example --- .../2-numeric-data-types/g-2210.md | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2210.md b/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2210.md index 6903bcbc..4a1ff713 100644 --- a/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2210.md +++ b/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2210.md @@ -10,27 +10,17 @@ If you do not specify precision `number` is defaulted to 38 or the maximum suppo ## Example (bad) ``` sql -create or replace package body constants_up is - co_small_increase constant number := 0.1; - - function small_increase return number is - begin - return co_small_increase; - end small_increase; -end constants_up; +create or replace package types_up is + subtype salary_type is number; +end types_up; / ``` ## Example (good) ``` sql -create or replace package body constants_up is - co_small_increase constant number(5,1) := 0.1; - - function small_increase return number is - begin - return co_small_increase; - end small_increase; -end constants_up; +create or replace package types_up is + subtype salary_type is number(5,1); +end types_up; / ``` \ No newline at end of file From 0fbb84f696b2790143dc1177b7539d5d96f76f66 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 13:26:38 +0200 Subject: [PATCH 33/63] Fix violations of G-7460, explain G-2130, G-2230 - new example demonstrating that pls_integer is faster than number --- .../2-numeric-data-types/g-2220.md | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2220.md b/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2220.md index a8659619..11c65595 100644 --- a/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2220.md +++ b/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2220.md @@ -15,27 +15,37 @@ There are many reasons to use `pls_integer` instead of `number`: ## Example (bad) ``` sql -create or replace package body constants_up is - co_big_increase constant number(5,0) := 1; - - function big_increase return number is - begin - return co_big_increase; - end big_increase; -end constants_up; +declare + l_result number(9,0) := 0; -- violates also G-2130, G-2230 + co_upper_bound constant pls_integer := 1e8; +begin + <> + for i in 1..co_upper_bound + loop + if i > 0 then + l_result := l_result + 1; + end if; + end loop burning_cpu; + sys.dbms_output.put_line(l_result); +end; / ``` ## Example (good) ``` sql -create or replace package body constants_up is - co_big_increase constant pls_integer := 1; - - function big_increase return pls_integer is - begin - return co_big_increase; - end big_increase; -end constants_up; +declare + l_result pls_integer := 0; + co_upper_bound constant pls_integer := 1e8; +begin + <> + for i in 1..co_upper_bound + loop + if i > 0 then + l_result := l_result + 1; + end if; + end loop burning_less_cpu; + sys.dbms_output.put_line(l_result); +end; / ``` \ No newline at end of file From a6994078a99fb07951c3eb8ff59e29055093af6b Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 15:22:06 +0200 Subject: [PATCH 34/63] Explain G-2130, G-2220, new example demonstrating that simple_integer is faster than number --- .../2-numeric-data-types/g-2230.md | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2230.md b/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2230.md index f0019bf9..826e9428 100644 --- a/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2230.md +++ b/docs/4-language-usage/2-variables-and-types/2-numeric-data-types/g-2230.md @@ -13,31 +13,37 @@ With Oracle Database 11g, the new data type `simple_integer` has been introduced ## Example (bad) ``` sql -create or replace package body constants_up is - co_big_increase constant number(5,0) := 1; - - function big_increase return number - deterministic - is - begin - return co_big_increase; - end big_increase; -end constants_up; +declare + l_result number(9,0) := 0; -- violates also G-2130, G-2220 + co_upper_bound constant pls_integer := 1e8; +begin + <> + for i in 1..co_upper_bound + loop + if i > 0 then + l_result := l_result + 1; + end if; + end loop burning_cpu; + sys.dbms_output.put_line(l_result); +end; / ``` ## Example (good) ``` sql -create or replace package body constants_up is - co_big_increase constant simple_integer := 1; - - function big_increase return simple_integer - deterministic - is - begin - return co_big_increase; - end big_increase; -end constants_up; +declare + l_result simple_integer := 0; + co_upper_bound constant pls_integer := 1e8; +begin + <> + for i in 1..co_upper_bound + loop + if i > 0 then + l_result := l_result + 1; + end if; + end loop burning_cpu; + sys.dbms_output.put_line(l_result); +end; / ``` \ No newline at end of file From 2adce4e49836b2f8366c1e6db104d3c04f24d4b2 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 16:28:11 +0200 Subject: [PATCH 35/63] Fix violations of G-7460, G-2130 --- .../3-character-data-types/g-2330.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/3-character-data-types/g-2330.md b/docs/4-language-usage/2-variables-and-types/3-character-data-types/g-2330.md index 27114ae3..72ada8dc 100644 --- a/docs/4-language-usage/2-variables-and-types/3-character-data-types/g-2330.md +++ b/docs/4-language-usage/2-variables-and-types/3-character-data-types/g-2330.md @@ -11,9 +11,11 @@ Today zero-length strings and `null` are currently handled identical by the Orac ``` sql create or replace package body constants_up is - co_null_string constant varchar2(1 char) := ''; + co_null_string constant types_up.text := ''; - function null_string return varchar2 is + function null_string return varchar2 + deterministic + is begin return co_null_string; end null_string; @@ -25,8 +27,9 @@ end constants_up; ``` sql create or replace package body constants_up is - - function empty_string return varchar2 is + function empty_string return varchar2 + deterministic + is begin return null; end empty_string; From efd8a13d926f51ac65d36ac22a24d9991adf8bd2 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 16:30:07 +0200 Subject: [PATCH 36/63] Fix violations of G-2135 --- .../2-variables-and-types/4-boolean-data-types/g-2410.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/4-language-usage/2-variables-and-types/4-boolean-data-types/g-2410.md b/docs/4-language-usage/2-variables-and-types/4-boolean-data-types/g-2410.md index 616ada77..6072a302 100644 --- a/docs/4-language-usage/2-variables-and-types/4-boolean-data-types/g-2410.md +++ b/docs/4-language-usage/2-variables-and-types/4-boolean-data-types/g-2410.md @@ -20,6 +20,7 @@ begin else l_bigger := constants_up.co_numeric_false; end if; + do_something(l_bigger); end; / ``` @@ -37,6 +38,7 @@ begin else l_bigger := false; end if; + do_something(l_bigger); end; / ``` @@ -50,6 +52,7 @@ declare l_bigger boolean; begin l_bigger := nvl(co_newfile < co_oldfile,false); + do_something(l_bigger); end; / ``` \ No newline at end of file From 93e20f454c09767a957a44125700c0c2f88a57de Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 17:08:17 +0200 Subject: [PATCH 37/63] Fix violation of G-7230, G-1030 - explain G-2130 --- .../5-large-objects/g-2510.md | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/docs/4-language-usage/2-variables-and-types/5-large-objects/g-2510.md b/docs/4-language-usage/2-variables-and-types/5-large-objects/g-2510.md index f6415905..a2d076b4 100644 --- a/docs/4-language-usage/2-variables-and-types/5-large-objects/g-2510.md +++ b/docs/4-language-usage/2-variables-and-types/5-large-objects/g-2510.md @@ -12,39 +12,25 @@ There are many constraints to `long` datatypes in comparison to the `lob` types. ## Example (bad) ``` sql -create or replace package example_package is - g_long long; - g_raw long raw; - - procedure do_something; -end example_package; -/ - -create or replace package body example_package is - procedure do_something is - begin - null; - end do_something; -end example_package; +declare + l_long long; -- violates also G-2130 + l_raw long raw; -- violates also G-2130 +begin + do_something(l_long); + do_something(l_raw); +end; / ``` ## Example (good) ``` sql -create or replace package example_package is - procedure do_something; -end example_package; -/ - -create or replace package body example_package is - g_long clob; - g_raw blob; - - procedure do_something is - begin - null; - end do_something; -end example_package; +declare + l_long clob; + l_raw blob; +begin + do_something(l_long); + do_something(l_raw); +end; / ``` \ No newline at end of file From ab4036bfe58dac0a33445f8e5e0bf46e85305520 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Jul 2023 17:15:40 +0200 Subject: [PATCH 38/63] Fix violations of G-1050 --- .../3-dml-and-sql/1-general/g-3110.md | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/docs/4-language-usage/3-dml-and-sql/1-general/g-3110.md b/docs/4-language-usage/3-dml-and-sql/1-general/g-3110.md index 2f89273c..12874e8d 100644 --- a/docs/4-language-usage/3-dml-and-sql/1-general/g-3110.md +++ b/docs/4-language-usage/3-dml-and-sql/1-general/g-3110.md @@ -10,25 +10,40 @@ Data structures often change. Having the target columns in your insert statement ## Example (bad) ``` sql -insert into departments -values ( - departments_seq.nextval - ,'Support' - ,100 - ,10); +create or replace package body dept_api is + procedure ins_dept(in_dept_row in dept%rowtype) is + begin + insert into departments + values ( + departments_seq.nextval + ,in_dept_row.department_name + ,in_dept_row.manager_id + ,in_dept_row.location_id + ); + end ins_dept; +end dept_api; +/ ``` ## Example (good) ``` sql -insert into departments ( - department_id - ,department_name - ,manager_id - ,location_id) -values ( - departments_seq.nextval - ,'Support' - ,100 - ,10); +create or replace package body dept_api is + procedure ins_dept(in_dept_row in dept%rowtype) is + begin + insert into departments ( + department_id + ,department_name + ,manager_id + ,location_id + ) + values ( + departments_seq.nextval + ,in_dept_row.department_name + ,in_dept_row.manager_id + ,in_dept_row.location_id + ); + end ins_dept; +end dept_api; +/ ``` \ No newline at end of file From e2ee234c45ba956a204378d70bccf8b3867cb9dd Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 11:18:35 +0200 Subject: [PATCH 39/63] Fix violation of G-4330 --- .../4-control-structures/1-cursor/g-4110.md | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md b/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md index cd3417af..a1421d90 100644 --- a/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md +++ b/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md @@ -12,20 +12,28 @@ The readability of your code will be higher when you avoid negative sentences. ``` sql declare cursor c_employees is - select last_name - ,first_name + select employee_id from employees where commission_pct is not null; - r_employee c_employees%rowtype; + type t_employee_type is table of c_employees%rowtype; + t_employee t_employee_type; + co_fetch_limit constant integer := 10; begin open c_employees; - <> + <> loop - fetch c_employees into r_employee; - exit read_employees when not c_employees%found; - end loop read_employees; + fetch c_employees bulk collect into t_employee limit co_fetch_limit; + + <> + for i in 1..t_employee.count + loop + my_package.process(t_employee(i).employee_id); + end loop read_employees; + + exit read_employee_batches when not c_employees%found; + end loop read_employee_batches; close c_employees; end; @@ -37,20 +45,28 @@ end; ``` sql declare cursor c_employees is - select last_name - ,first_name + select employee_id from employees where commission_pct is not null; - r_employee c_employees%rowtype; + type t_employee_type is table of c_employees%rowtype; + t_employee t_employee_type; + co_fetch_limit constant integer := 10; begin open c_employees; - <> + <> loop - fetch c_employees into r_employee; - exit read_employees when c_employees%notfound; - end loop read_employees; + fetch c_employees bulk collect into t_employee limit co_fetch_limit; + + <> + for i in 1..t_employee.count + loop + my_package.process(t_employee(i).employee_id); + end loop read_employees; + + exit read_employee_batches when c_employees%notfound; + end loop read_employee_batches; close c_employees; end; From c21ed656f9ccab491943cfe3b56d164d5e47b03c Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 11:39:03 +0200 Subject: [PATCH 40/63] use plural for array name --- .../4-control-structures/1-cursor/g-4110.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md b/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md index a1421d90..69b86178 100644 --- a/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md +++ b/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md @@ -16,20 +16,20 @@ declare from employees where commission_pct is not null; - type t_employee_type is table of c_employees%rowtype; - t_employee t_employee_type; + type t_employees_type is table of c_employees%rowtype; + t_employees t_employees_type; co_fetch_limit constant integer := 10; begin open c_employees; <> loop - fetch c_employees bulk collect into t_employee limit co_fetch_limit; + fetch c_employees bulk collect into t_employees limit co_fetch_limit; <> - for i in 1..t_employee.count + for i in 1..t_employees.count loop - my_package.process(t_employee(i).employee_id); + my_package.process(t_employees(i).employee_id); end loop read_employees; exit read_employee_batches when not c_employees%found; @@ -49,20 +49,20 @@ declare from employees where commission_pct is not null; - type t_employee_type is table of c_employees%rowtype; - t_employee t_employee_type; + type t_employees_type is table of c_employees%rowtype; + t_employees t_employees_type; co_fetch_limit constant integer := 10; begin open c_employees; <> loop - fetch c_employees bulk collect into t_employee limit co_fetch_limit; + fetch c_employees bulk collect into t_employees limit co_fetch_limit; <> - for i in 1..t_employee.count + for i in 1..t_employees.count loop - my_package.process(t_employee(i).employee_id); + my_package.process(t_employees(i).employee_id); end loop read_employees; exit read_employee_batches when c_employees%notfound; From 70e6f28bbbc8ec45c1851906f32bed0d84b984c0 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 11:49:47 +0200 Subject: [PATCH 41/63] reuse example of G-4120 in G-4120 --- .../4-control-structures/1-cursor/g-4110.md | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md b/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md index 69b86178..727b303c 100644 --- a/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md +++ b/docs/4-language-usage/4-control-structures/1-cursor/g-4110.md @@ -12,28 +12,28 @@ The readability of your code will be higher when you avoid negative sentences. ``` sql declare cursor c_employees is - select employee_id + select * from employees - where commission_pct is not null; + order by employee_id; type t_employees_type is table of c_employees%rowtype; - t_employees t_employees_type; - co_fetch_limit constant integer := 10; + t_employees t_employees_type; + co_bulk_size constant simple_integer := 10; begin open c_employees; - <> + <> loop - fetch c_employees bulk collect into t_employees limit co_fetch_limit; + fetch c_employees bulk collect into t_employees limit co_bulk_size; - <> - for i in 1..t_employees.count + <> + for i in 1..t_employees.count() loop - my_package.process(t_employees(i).employee_id); - end loop read_employees; + sys.dbms_output.put_line(t_employees(i).last_name); + end loop display_employees; - exit read_employee_batches when not c_employees%found; - end loop read_employee_batches; + exit process_employees when not c_employees%found; + end loop process_employees; close c_employees; end; @@ -45,28 +45,28 @@ end; ``` sql declare cursor c_employees is - select employee_id + select * from employees - where commission_pct is not null; + order by employee_id; type t_employees_type is table of c_employees%rowtype; - t_employees t_employees_type; - co_fetch_limit constant integer := 10; + t_employees t_employees_type; + co_bulk_size constant simple_integer := 10; begin open c_employees; - <> + <> loop - fetch c_employees bulk collect into t_employees limit co_fetch_limit; + fetch c_employees bulk collect into t_employees limit co_bulk_size; - <> - for i in 1..t_employees.count + <> + for i in 1..t_employees.count() loop - my_package.process(t_employees(i).employee_id); - end loop read_employees; + sys.dbms_output.put_line(t_employees(i).last_name); + end loop display_employees; - exit read_employee_batches when c_employees%notfound; - end loop read_employee_batches; + exit process_employees when c_employees%notfound; + end loop process_employees; close c_employees; end; From 883ae5f90b3f9b707d64aae68c3662046931c35a Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 11:57:02 +0200 Subject: [PATCH 42/63] Fix violation of G-2130 --- .../2-case-if-decode-nvl-nvl2-coalesce/g-4260.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/4-language-usage/4-control-structures/2-case-if-decode-nvl-nvl2-coalesce/g-4260.md b/docs/4-language-usage/4-control-structures/2-case-if-decode-nvl-nvl2-coalesce/g-4260.md index ca4dc672..cb3ec5a0 100644 --- a/docs/4-language-usage/4-control-structures/2-case-if-decode-nvl-nvl2-coalesce/g-4260.md +++ b/docs/4-language-usage/4-control-structures/2-case-if-decode-nvl-nvl2-coalesce/g-4260.md @@ -11,7 +11,7 @@ It is more readable to use the opposite comparison operator instead of inverting ``` sql declare - l_color varchar2(7 char); + l_color types_up.color_code_type; begin if not l_color != constants_up.co_red then my_package.do_red(); From 9c4b16ce223aad87abf5875932aa7c10ea64e3be Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 12:51:48 +0200 Subject: [PATCH 43/63] Fix violations of G-1050 and G-2130 --- .../2-case-if-decode-nvl-nvl2-coalesce/g-4270.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/4-language-usage/4-control-structures/2-case-if-decode-nvl-nvl2-coalesce/g-4270.md b/docs/4-language-usage/4-control-structures/2-case-if-decode-nvl-nvl2-coalesce/g-4270.md index ed101cd8..e4ac66d2 100644 --- a/docs/4-language-usage/4-control-structures/2-case-if-decode-nvl-nvl2-coalesce/g-4270.md +++ b/docs/4-language-usage/4-control-structures/2-case-if-decode-nvl-nvl2-coalesce/g-4270.md @@ -11,10 +11,10 @@ It is more readable to simply use the boolean value as a condition itself, rathe ``` sql declare - l_string varchar2(10 char) := '42'; + co_string constant types_up.text := '42'; l_is_valid boolean; begin - l_is_valid := my_package.is_valid_number(l_string); + l_is_valid := my_package.is_valid_number(co_string); if l_is_valid = true then my_package.convert_number(l_string); end if; @@ -26,10 +26,10 @@ end; ``` sql declare - l_string varchar2(10 char) := '42'; + co_string constant types_up.text := '42'; l_is_valid boolean; begin - l_is_valid := my_package.is_valid_number(l_string); + l_is_valid := my_package.is_valid_number(co_string); if l_is_valid then my_package.convert_number(l_string); end if; From f315157a56898f0afb48a1e28fad18a30734763b Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 13:07:08 +0200 Subject: [PATCH 44/63] Fix violations of G-1050 --- .../5-exception-handling/g-5010.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/4-language-usage/5-exception-handling/g-5010.md b/docs/4-language-usage/5-exception-handling/g-5010.md index f0a1dcf0..f22edad4 100644 --- a/docs/4-language-usage/5-exception-handling/g-5010.md +++ b/docs/4-language-usage/5-exception-handling/g-5010.md @@ -21,10 +21,13 @@ This kind of framework should include ## Example (bad) ``` sql +declare + co_start constant logger_logs.text%type := 'start'; + co_end constant logger_logs.text%type := 'end'; begin - sys.dbms_output.put_line('START'); + sys.dbms_output.put_line(co_start); -- some processing - sys.dbms_output.put_line('END'); + sys.dbms_output.put_line(co_end); end; / ``` @@ -34,11 +37,13 @@ end; ``` sql declare -- see https://github.com/OraOpenSource/Logger - l_scope logger_logs.scope%type := 'DEMO'; + co_start constant logger_logs.text%type := 'start'; + co_end constant logger_logs.text%type := 'end'; + co_scope constant logger_logs.scope%type := 'demo'; begin - logger.log('START',l_scope); + logger.log(co_start,co_scope); -- some processing - logger.log('END',l_scope); + logger.log(co_end,co_scope); end; / ``` \ No newline at end of file From a8fca87ea70cf81a40310c8b41d443156acaec44 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 14:16:09 +0200 Subject: [PATCH 45/63] Fix violation of G-5070 and explain violation of G-9113 --- docs/4-language-usage/5-exception-handling/g-5030.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/5-exception-handling/g-5030.md b/docs/4-language-usage/5-exception-handling/g-5030.md index e773f7e3..c99a335a 100644 --- a/docs/4-language-usage/5-exception-handling/g-5030.md +++ b/docs/4-language-usage/5-exception-handling/g-5030.md @@ -24,7 +24,7 @@ begin where rownum = co_rownum; if l_dummy is null then - raise no_data_found; + raise no_data_found; -- NOSONAR: consequential error, violates G-5070 end if; exception when no_data_found then @@ -35,7 +35,7 @@ end; ``` Error report - ORA-01403: no data found -ORA-06512: at line 5 +ORA-06512: at line 7 01403. 00000 - "no data found" *Cause: No data was found from the objects. *Action: There was no data from the objects which may be due to end of fetch. From 349b91562cb9d80b9dc6641db511f6564cae205d Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 14:26:17 +0200 Subject: [PATCH 46/63] Fix one violation of G-1050 and explain the other --- docs/4-language-usage/5-exception-handling/g-5050.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/4-language-usage/5-exception-handling/g-5050.md b/docs/4-language-usage/5-exception-handling/g-5050.md index e3a07455..3c28a0b9 100644 --- a/docs/4-language-usage/5-exception-handling/g-5050.md +++ b/docs/4-language-usage/5-exception-handling/g-5050.md @@ -10,8 +10,10 @@ If you are not very organized in the way you allocate, define and use the error ## Example (bad) ``` sql +declare + co_invalid_emp_text constant types_up.text := 'Invalid employee_id'; begin - raise_application_error(-20501,'Invalid employee_id'); + raise_application_error(-20501 /* violates also G-1010 */,co_invalid_emp_text); end; / ``` From 87d1aa75ed3e5fffa5f25c49b8828b2388d47a48 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 14:34:02 +0200 Subject: [PATCH 47/63] Fix violations of G-7460 --- docs/4-language-usage/5-exception-handling/g-5060.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/5-exception-handling/g-5060.md b/docs/4-language-usage/5-exception-handling/g-5060.md index 4acbd733..d83fe8a9 100644 --- a/docs/4-language-usage/5-exception-handling/g-5060.md +++ b/docs/4-language-usage/5-exception-handling/g-5060.md @@ -15,7 +15,7 @@ The form that this failure takes does not necessarily need to be an exception. W ``` sql create or replace package body department_api is - function name_by_id(in_id in departments.department_id%type) + function name_by_id(in_id in departments.department_id%type) -- NOSONAR: non-deterministic return departments.department_name%type is co_id constant departments.department_id%type := in_id; l_department_name departments.department_name%type; @@ -35,7 +35,7 @@ end department_api; ``` sql create or replace package body department_api is - function name_by_id(in_id in departments.department_id%type) + function name_by_id(in_id in departments.department_id%type) -- NOSONAR: non-deterministic return departments.department_name%type is co_id constant departments.department_id%type := in_id; l_department_name departments.department_name%type; From ea1e447547b04551ff599e01bd7b213b88fd3d26 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 14:40:08 +0200 Subject: [PATCH 48/63] Fix violations of G-1050 --- .../4-language-usage/5-exception-handling/g-5080.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/4-language-usage/5-exception-handling/g-5080.md b/docs/4-language-usage/5-exception-handling/g-5080.md index 5b4a107c..6837c59f 100644 --- a/docs/4-language-usage/5-exception-handling/g-5080.md +++ b/docs/4-language-usage/5-exception-handling/g-5080.md @@ -19,6 +19,7 @@ create or replace package body order_api as ) is co_customer_id constant customer.id%type := in_customer_id; co_discount constant customer.discount_percentage%type := in_discount; + co_error_label constant type_up.text := 'Error: '; begin customer_api.apply_discount( in_customer_id => co_customer_id @@ -29,7 +30,7 @@ create or replace package body order_api as when zero_divide then null; -- ignore when others then - logging_package.log_error('Error: ' || sqlerrm); + logging_package.log_error(co_error_label || sqlerrm); raise; end discount_and_recalculate; end order_api; @@ -44,8 +45,10 @@ create or replace package body order_api as in_customer_id in integer ,in_discount in number ) is - co_customer_id constant customer.id%type := in_customer_id; - co_discount constant customer.discount_percentage%type := in_discount; + co_customer_id constant customer.id%type := in_customer_id; + co_discount constant customer.discount_percentage%type := in_discount; + co_error_label constant type_up.text := 'Error: '; + co_backtrace_label constant type_up.text := ' - Backtrace: '; begin customer_api.apply_discount( in_customer_id => co_customer_id @@ -57,9 +60,9 @@ create or replace package body order_api as null; -- ignore when others then logging_package.log_error( - 'Error: ' + co_error_label || sqlerrm - || ' - Backtrace: ' + || co_backtrace_label || sys.dbms_utility.format_error_backtrace ); raise; From 9422bf872dce54dd4a20d8624585bb1bbb4fcf59 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 14:45:21 +0200 Subject: [PATCH 49/63] Explain violation of G-1050 --- docs/4-language-usage/6-dynamic-sql/g-6010.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/4-language-usage/6-dynamic-sql/g-6010.md b/docs/4-language-usage/6-dynamic-sql/g-6010.md index 9d28d280..bfe57ffb 100644 --- a/docs/4-language-usage/6-dynamic-sql/g-6010.md +++ b/docs/4-language-usage/6-dynamic-sql/g-6010.md @@ -13,7 +13,8 @@ Having the executed statement in a variable makes it easier to debug your code ( declare l_next_val employees.employee_id%type; begin - execute immediate 'select employees_seq.nextval from dual' into l_next_val; + execute immediate 'select employees_seq.nextval from dual' -- violates also G-1050 + into l_next_val; end; / ``` From 19107661bbc7f92fcb8857ae0e0443bbfc99b337 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 14:49:45 +0200 Subject: [PATCH 50/63] Put ever parameter using named notation on a dedicated line --- docs/4-language-usage/7-stored-objects/1-general/g-7110.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7110.md b/docs/4-language-usage/7-stored-objects/1-general/g-7110.md index 6a0a8997..4c332bfc 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7110.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7110.md @@ -28,7 +28,10 @@ declare r_employee employees%rowtype; co_id constant employees.employee_id%type := 107; begin - employee_api.employee_by_id(out_row => r_employee,in_employee_id => co_id); + employee_api.employee_by_id( + out_row => r_employee + ,in_employee_id => co_id + ); end; / ``` \ No newline at end of file From 20387fb53f4e5e259ff2e07cbf2a76ccc74a6b10 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 14:54:51 +0200 Subject: [PATCH 51/63] Fix violations of G-7460 --- .../4-language-usage/7-stored-objects/1-general/g-7140.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7140.md b/docs/4-language-usage/7-stored-objects/1-general/g-7140.md index f16b0b46..8b77cdfc 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7140.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7140.md @@ -16,7 +16,9 @@ There is never a better time to review all the steps you took, and to understand ``` sql create or replace package body my_package is procedure my_procedure is - function my_func return number is + function my_func return number + deterministic + is co_true constant integer := 1; begin return co_true; @@ -33,7 +35,9 @@ end my_package; ``` sql create or replace package body my_package is procedure my_procedure is - function my_func return number is + function my_func return number + deterministic + is co_true constant integer := 1; begin return co_true; From ffd91be5ea9188434bab055d29a809635c4e77db Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 15:05:14 +0200 Subject: [PATCH 52/63] Fix violations of G-8310 and reformat code --- .../7-stored-objects/1-general/g-7170.md | 62 +++++++++++-------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/docs/4-language-usage/7-stored-objects/1-general/g-7170.md b/docs/4-language-usage/7-stored-objects/1-general/g-7170.md index 75a7572e..92b8401c 100644 --- a/docs/4-language-usage/7-stored-objects/1-general/g-7170.md +++ b/docs/4-language-usage/7-stored-objects/1-general/g-7170.md @@ -14,24 +14,29 @@ Avoid using parameter mode `in out` unless you actually use the parameter both a ``` sql create or replace package body employee_up is - procedure rcv_emp(io_first_name in out employees.first_name%type - ,io_last_name in out employees.last_name%type - ,io_email in out employees.email%type - ,io_phone_number in out employees.phone_number%type - ,io_hire_date in out employees.hire_date%type - ,io_job_id in out employees.job_id%type - ,io_salary in out employees.salary%type - ,io_commission_pct in out employees.commission_pct%type - ,io_manager_id in out employees.manager_id%type - ,io_department_id in out employees.department_id%type - ,in_wait in integer) is + procedure rcv_emp( + io_first_name in out employees.first_name%type + ,io_last_name in out employees.last_name%type + ,io_email in out employees.email%type + ,io_phone_number in out employees.phone_number%type + ,io_hire_date in out employees.hire_date%type + ,io_job_id in out employees.job_id%type + ,io_salary in out employees.salary%type + ,io_commission_pct in out employees.commission_pct%type + ,io_manager_id in out employees.manager_id%type + ,io_department_id in out employees.department_id%type + ,in_wait in integer + ) is l_status pls_integer; co_dflt_pipe_name constant string(30 char) := 'MyPipe'; co_ok constant pls_integer := 1; + co_wait constant pls_integer := in_wait; begin -- Receive next message and unpack for each column. - l_status := sys.dbms_pipe.receive_message(pipename => co_dflt_pipe_name - ,timeout => in_wait); + l_status := sys.dbms_pipe.receive_message( + pipename => co_dflt_pipe_name + ,timeout => co_wait + ); if l_status = co_ok then sys.dbms_pipe.unpack_message(io_first_name); sys.dbms_pipe.unpack_message(io_last_name); @@ -53,24 +58,29 @@ end employee_up; ``` sql create or replace package body employee_up is - procedure rcv_emp(out_first_name out employees.first_name%type - ,out_last_name out employees.last_name%type - ,out_email out employees.email%type - ,out_phone_number out employees.phone_number%type - ,out_hire_date out employees.hire_date%type - ,out_job_id out employees.job_id%type - ,out_salary out employees.salary%type - ,out_commission_pct out employees.commission_pct%type - ,out_manager_id out employees.manager_id%type - ,out_department_id out employees.department_id%type - ,in_wait in integer) is + procedure rcv_emp( + out_first_name out employees.first_name%type + ,out_last_name out employees.last_name%type + ,out_email out employees.email%type + ,out_phone_number out employees.phone_number%type + ,out_hire_date out employees.hire_date%type + ,out_job_id out employees.job_id%type + ,out_salary out employees.salary%type + ,out_commission_pct out employees.commission_pct%type + ,out_manager_id out employees.manager_id%type + ,out_department_id out employees.department_id%type + ,in_wait in integer + ) is l_status pls_integer; co_dflt_pipe_name constant string(30 char) := 'MyPipe'; co_ok constant pls_integer := 1; + co_wait constant pls_integer := in_wait; begin -- Receive next message and unpack for each column. - l_status := sys.dbms_pipe.receive_message(pipename => co_dflt_pipe_name - ,timeout => in_wait); + l_status := sys.dbms_pipe.receive_message( + pipename => co_dflt_pipe_name + ,timeout => co_wait + ); if l_status = co_ok then sys.dbms_pipe.unpack_message(out_first_name); sys.dbms_pipe.unpack_message(out_last_name); From aeec9b4d6da549ee088afa3112b5aac5f9e22613 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 15:15:22 +0200 Subject: [PATCH 53/63] Fix violation of G-8110 --- .../8-patterns/1-checking-the-number-of-rows/g-8120.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/4-language-usage/8-patterns/1-checking-the-number-of-rows/g-8120.md b/docs/4-language-usage/8-patterns/1-checking-the-number-of-rows/g-8120.md index 7125646d..66103b04 100644 --- a/docs/4-language-usage/8-patterns/1-checking-the-number-of-rows/g-8120.md +++ b/docs/4-language-usage/8-patterns/1-checking-the-number-of-rows/g-8120.md @@ -14,7 +14,7 @@ create or replace package body department_api is procedure ins(in_r_department in departments%rowtype) is l_count pls_integer; begin - select count(*) + select count(*) -- NOSONAR: a violation of G-8110 is a prerequisite for G-8120 into l_count from departments where department_id = in_r_department.department_id; From 6f523eb4ddcf9c1919ced90ff4c3dbbeba50b5bd Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 16:07:06 +0200 Subject: [PATCH 54/63] Fix violations of G-1050, G-5060, G-7460 --- .../g-8310.md | 59 +++++++++++++------ 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/docs/4-language-usage/8-patterns/3-validating-input-parameter-size/g-8310.md b/docs/4-language-usage/8-patterns/3-validating-input-parameter-size/g-8310.md index d4dbe67b..c5d671de 100644 --- a/docs/4-language-usage/8-patterns/3-validating-input-parameter-size/g-8310.md +++ b/docs/4-language-usage/8-patterns/3-validating-input-parameter-size/g-8310.md @@ -11,20 +11,30 @@ This technique raises an error (`value_error`) which may not be handled in the c ``` sql create or replace package body department_api is - function dept_by_name(in_dept_name in departments.department_name%type) + function dept_by_name( -- NOSONAR: non-deterministic + in_dept_name in departments.department_name%type + ) return departments%rowtype is - r_return departments%rowtype; + r_return departments%rowtype; + co_max_dept_name_length constant integer := 20; begin - if in_dept_name is null or length(in_dept_name) > 20 then + if in_dept_name is null or length(in_dept_name) > co_max_dept_name_length then raise err.e_param_to_large; end if; -- get the department by name - select * - into r_return - from departments - where department_name = in_dept_name; - - return r_return; + <> + begin + select * + into r_return + from departments + where department_name = in_dept_name; + return r_return; + exception + when no_data_found then + return null; + when too_many_rows then + raise; + end trap; end dept_by_name; end department_api; / @@ -34,18 +44,27 @@ end department_api; ``` sql create or replace package body department_api is - function dept_by_name(in_dept_name in departments.department_name%type) + function dept_by_name( -- NOSONAR: non-deterministic + in_dept_name in departments.department_name%type + ) return departments%rowtype is - l_dept_name departments.department_name%type not null := in_dept_name; - r_return departments%rowtype; + co_dept_name constant departments.department_name%type not null := in_dept_name; + r_return departments%rowtype; begin -- get the department by name - select * - into r_return - from departments - where department_name = l_dept_name; - - return r_return; + <> + begin + select * + into r_return + from departments + where department_name = co_dept_name; + return r_return; + exception + when no_data_found then + return null; + when too_many_rows then + raise; + end trap; end dept_by_name; end department_api; / @@ -54,9 +73,11 @@ end department_api; The exception should be handled where the function is called, like this: ``` sql +declare + co_dept_name constant type_up.text := 'Far to long name of a department'; begin pre_processing; - r_department := department_api.dept_by_name('Far to long name of a department'); + r_department := department_api.dept_by_name(co_dept_name); post_processing; exception when value_error then From e04603b918c38498cf162ca0725575d9792690ce Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 16:34:19 +0200 Subject: [PATCH 55/63] Fix violations of G-2130, G-5040, G-7460, G-8310 --- .../g-8410.md | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/docs/4-language-usage/8-patterns/4-ensure-single-execution-at-a-time-of-a-program-unit/g-8410.md b/docs/4-language-usage/8-patterns/4-ensure-single-execution-at-a-time-of-a-program-unit/g-8410.md index 4db1663b..43041921 100644 --- a/docs/4-language-usage/8-patterns/4-ensure-single-execution-at-a-time-of-a-program-unit/g-8410.md +++ b/docs/4-language-usage/8-patterns/4-ensure-single-execution-at-a-time-of-a-program-unit/g-8410.md @@ -15,7 +15,6 @@ The alternative using a table where a “Lock-Row” is stored has the disadvant ## Example (bad) ``` sql --- Bad /* Example */ create or replace package body lock_up is -- manage locks in a dedicated table created as follows: @@ -24,28 +23,34 @@ create or replace package body lock_up is -- ); procedure request_lock(in_lock_name in varchar2) is + co_lock_name constant app_locks.lock_name%type := in_lock_name; begin -- raises dup_val_on_index - insert into app_locks (lock_name) values (in_lock_name); + insert into app_locks (lock_name) values (co_lock_name); end request_lock; procedure release_lock(in_lock_name in varchar2) is + co_lock_name constant app_locks.lock_name%type := in_lock_name; begin - delete from app_locks where lock_name = in_lock_name; + delete from app_locks where lock_name = co_lock_name; end release_lock; end lock_up; / /* Call bad example */ declare - co_lock_name constant varchar2(30 char) := 'APPLICATION_LOCK'; + co_lock_name constant app_locks.lock_name%type := 'APPLICATION_LOCK'; begin lock_up.request_lock(in_lock_name => co_lock_name); -- processing lock_up.release_lock(in_lock_name => co_lock_name); exception + when dup_val_on_index then + -- expected exception + lock_up.release_lock(in_lock_name => co_lock_name); + raise; when others then - -- log error + -- unexpected exception, logging is recommended lock_up.release_lock(in_lock_name => co_lock_name); raise; end; @@ -57,14 +62,17 @@ end; ``` sql /* Example */ create or replace package body lock_up is - function request_lock( + function request_lock( -- NOSONAR: non-deterministic in_lock_name in varchar2 - ,in_release_on_commit in boolean := false) + ,in_release_on_commit in boolean default false + ) return varchar2 is - l_lock_handle varchar2(128 char); + co_lock_name constant type_up.lock_name := in_lock_name; + co_release_on_commit constant boolean := in_release_on_commit; + l_lock_handle type_up.lock_handle; begin sys.dbms_lock.allocate_unique( - lockname => in_lock_name + lockname => co_lock_name ,lockhandle => l_lock_handle ,expiration_secs => constants_up.co_one_week ); @@ -72,7 +80,7 @@ create or replace package body lock_up is lockhandle => l_lock_handle ,lockmode => sys.dbms_lock.x_mode ,timeout => sys.dbms_lock.maxwait - ,release_on_commit => coalesce(in_release_on_commit,false) + ,release_on_commit => co_release_on_commit ) > 0 then raise err.e_lock_request_failed; @@ -81,8 +89,9 @@ create or replace package body lock_up is end request_lock; procedure release_lock(in_lock_handle in varchar2) is + co_lock_type constant type_up.lock_handle := in_lock_handle; begin - if sys.dbms_lock.release(lockhandle => in_lock_handle) > 0 then + if sys.dbms_lock.release(lockhandle => co_lock_type) > 0 then raise err.e_lock_request_failed; end if; end release_lock; @@ -91,16 +100,20 @@ end lock_up; /* Call good example */ declare - l_handle varchar2(128 char); - co_lock_name constant varchar2(30 char) := 'APPLICATION_LOCK'; + l_handle type_up.lock_handle; + co_lock_name constant type_up.lock_name := 'APPLICATION_LOCK'; begin l_handle := lock_up.request_lock(in_lock_name => co_lock_name); -- processing lock_up.release_lock(in_lock_handle => l_handle); exception + when err.e_lock_request_failed then + -- expected exception + lock_up.release_lock(in_lock_name => co_lock_name); + raise; when others then - -- log error - lock_up.release_lock(in_lock_handle => l_handle); + -- unexpected exception, logging is recommended + lock_up.release_lock(in_lock_name => co_lock_name); raise; end; / From 4b3f4974fa2a2e0107b8816e4a3fe79aa06cbc7a Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 16:49:00 +0200 Subject: [PATCH 56/63] Fix violations of G-1050 and G-4385 --- .../g-8510.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/4-language-usage/8-patterns/5-use-dbms-application-info-package-to-follow-progress-of-a-process/g-8510.md b/docs/4-language-usage/8-patterns/5-use-dbms-application-info-package-to-follow-progress-of-a-process/g-8510.md index 80fe853d..4187dc4d 100644 --- a/docs/4-language-usage/8-patterns/5-use-dbms-application-info-package-to-follow-progress-of-a-process/g-8510.md +++ b/docs/4-language-usage/8-patterns/5-use-dbms-application-info-package-to-follow-progress-of-a-process/g-8510.md @@ -23,7 +23,8 @@ create or replace package body employee_api is order by employee_id ) loop - null; -- some processing + -- some processing + sys.dbms_output.put_line(emp_rec.employee_id); end loop employees; end process_emps; end employee_api; @@ -35,9 +36,13 @@ end employee_api; ``` sql create or replace package body employee_api is procedure process_emps is + co_action_name constant v$session.action%type := 'init'; + co_label constant v$session.action%type := 'Processing '; begin - sys.dbms_application_info.set_module(module_name => $$plsql_unit - ,action_name => 'Init'); + sys.dbms_application_info.set_module( + module_name => $$plsql_unit + ,action_name => co_action_name + ); <> for emp_rec in ( select employee_id @@ -45,7 +50,8 @@ create or replace package body employee_api is order by employee_id ) loop - sys.dbms_application_info.set_action('Processing ' || emp_rec.employee_id); + -- some processing + sys.dbms_application_info.set_action(co_label || emp_rec.employee_id); end loop employees; end process_emps; end employee_api; From fbdd65e19fdba84b6550fb735346d2df509fdd6b Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 25 Aug 2023 17:45:13 +0200 Subject: [PATCH 57/63] Fix violations of G-8310, G-1050, G-9030, explain G-9030 --- .../9-function-usage/g-9010.md | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/4-language-usage/9-function-usage/g-9010.md b/docs/4-language-usage/9-function-usage/g-9010.md index 085dd904..ecdfbc12 100644 --- a/docs/4-language-usage/9-function-usage/g-9010.md +++ b/docs/4-language-usage/9-function-usage/g-9010.md @@ -13,12 +13,16 @@ Using an explicit format model for string to `date` or `timestamp` conversion av ``` sql create or replace package body employee_api is - procedure set_dob(in_employee_id in employees.employee_id%type - ,in_dob_str in varchar2) is + procedure set_dob( + in_employee_id in employees.employee_id%type + ,in_dob_str in varchar2 + ) is + co_employee_id constant employees.employee_id%type := in_employee_id; + co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(in_dob_str) - where employee_id = in_employee_id; + set date_of_birth = to_date(co_dob_str) -- violates also G-9030 + where employee_id = co_employee_id; end set_dob; end employee_api; / @@ -28,12 +32,16 @@ end employee_api; ``` sql create or replace package body employee_api is - procedure set_dob(in_employee_id in employees.employee_id%type - ,in_dob_str in varchar2) is + procedure set_dob( + in_employee_id in employees.employee_id%type + ,in_dob_str in varchar2 + ) is + co_employee_id constant employees.employee_id%type := in_employee_id; + co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(in_dob_str,'FXYYYY-MM-DD') - where employee_id = in_employee_id; + set date_of_birth = to_date(co_dob_str default null on conversion error,'FXYYYY-MM-DD') -- NOSONAR G-1050 must be a literal + where employee_id = co_employee_id; end set_dob; end employee_api; / From 4639692f6fa6b4c3c9c137eef4bad8dd2d8cf146 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 1 Sep 2023 12:10:30 +0200 Subject: [PATCH 58/63] Fix violations of G-1050, G-8310, explain G-9030 --- .../9-function-usage/g-9020.md | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/4-language-usage/9-function-usage/g-9020.md b/docs/4-language-usage/9-function-usage/g-9020.md index fd8190b2..1b54b44c 100644 --- a/docs/4-language-usage/9-function-usage/g-9020.md +++ b/docs/4-language-usage/9-function-usage/g-9020.md @@ -13,12 +13,16 @@ To avoid an inappropriate dependability on configurable NLS parameters, try to u ``` sql create or replace package body employee_api is - procedure set_salary(in_employee_id in employees.employee_id%type - ,in_salary in varchar2) is + procedure set_salary( + in_employee_id in employees.employee_id%type + ,in_salary in varchar2 + ) is + co_employee_id constant eployees.employee_id%type := in_employee_id; + co_salary constant type_up.date_string := in_salary; begin update employees - set salary = to_number(in_salary) - where employee_id = in_employee_id; + set salary = to_number(co_salary) -- violates also G-9030 + where employee_id = co_employee_id; end set_dob; end employee_api; / @@ -28,13 +32,20 @@ end employee_api; ``` sql create or replace package body employee_api is - procedure set_salary(in_employee_id in employees.employee_id%type - ,in_salary in varchar2) is + procedure set_salary( + in_employee_id in employees.employee_id%type + ,in_salary in varchar2 + ) is + co_employee_id constant eployees.employee_id%type := in_employee_id; + co_salary constant type_up.string := in_salary; begin update employees - set salary = to_number(in_salary,'99999999999999999999.99999',q'[nls_numeric_characters='.,']') - where employee_id = in_employee_id; + set salary = to_number( + co_salary default null on conversion error + ,'99999999999999999999.99999' -- NOSONAR G-1050 must be a literal + ,q'[nls_numeric_characters='.,']' -- NOSONAR G-1050 must be a literal + ) + where employee_id = co_employee_id; end set_dob; end employee_api; -/ -``` \ No newline at end of file +``` From d2ea4e1303295c163be7658d81b6c983d2c26a71 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 1 Sep 2023 12:29:54 +0200 Subject: [PATCH 59/63] Fix violations of G-1050, G-8310, G-9040 --- .../9-function-usage/g-9030.md | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/4-language-usage/9-function-usage/g-9030.md b/docs/4-language-usage/9-function-usage/g-9030.md index c218f227..6057ac23 100644 --- a/docs/4-language-usage/9-function-usage/g-9030.md +++ b/docs/4-language-usage/9-function-usage/g-9030.md @@ -15,12 +15,17 @@ When converting from strings to other datatypes using a conversion function that ``` sql create or replace package body employee_api is - procedure set_dob(in_employee_id in employees.employee_id%type - ,in_dob_str in varchar2) is + procedure set_dob( + in_employee_id in employees.employee_id%type + ,in_dob_str in varchar2 + ) is + co_employee_id constant employees.employee_id%type := in_employee_id; + co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(in_dob_str,'YYYY-MM-DD') - where employee_id = in_employee_id; + set date_of_birth = to_date(co_dob_str,'FXYYYY-MM-DD' -- NOSONAR G-1050 must be a literal +) + where employee_id = co_employee_id; end set_dob; end employee_api; / @@ -30,12 +35,19 @@ end employee_api; ``` sql create or replace package body employee_api is - procedure set_dob(in_employee_id in employees.employee_id%type - ,in_dob_str in varchar2) is + procedure set_dob( + in_employee_id in employees.employee_id%type + ,in_dob_str in varchar2 + ) is + co_employee_id constant employees.employee_id%type := in_employee_id; + co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(in_dob_str default null on conversion error,'YYYY-MM-DD') - where employee_id = in_employee_id; + set date_of_birth = to_date( + co_dob_str default null on conversion error + ,'FXYYYY-MM-DD' -- NOSONAR G-1050 must be a literal + ) + where employee_id = co_employee_id; end set_dob; end employee_api; / From db5611e7883bf3d11a717f9c86218dce06ad789b Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 1 Sep 2023 12:34:37 +0200 Subject: [PATCH 60/63] Fix violations of G-8310, G-9030, explain G-1050 --- .../9-function-usage/g-9040.md | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/docs/4-language-usage/9-function-usage/g-9040.md b/docs/4-language-usage/9-function-usage/g-9040.md index 247baaf3..20ba8b99 100644 --- a/docs/4-language-usage/9-function-usage/g-9040.md +++ b/docs/4-language-usage/9-function-usage/g-9040.md @@ -15,12 +15,19 @@ The exception to this rule can be if you are converting textual input typed by a ``` sql create or replace package body employee_api is - procedure set_dob(in_employee_id in employees.employee_id%type - ,in_dob_str in varchar2) is + procedure set_dob( + in_employee_id in employees.employee_id%type + ,in_dob_str in varchar2 + ) is + co_employee_id constant employees.employee_id%type := in_employee_id; + co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(in_dob_str,'YYYY-MM-DD') - where employee_id = in_employee_id; + set date_of_birth = to_date( + co_dob_str default null on conversion error + ,'YYYY-MM-DD' -- violates also G-1050, must be a literal + ) + where employee_id = co_employee_id; end set_dob; end employee_api; / @@ -30,12 +37,19 @@ end employee_api; ``` sql create or replace package body employee_api is - procedure set_dob(in_employee_id in employees.employee_id%type - ,in_dob_str in varchar2) is + procedure set_dob( + in_employee_id in employees.employee_id%type + ,in_dob_str in varchar2 + ) is + co_employee_id constant employees.employee_id%type := in_employee_id; + co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(in_dob_str,'FXYYYY-MM-DD') - where employee_id = in_employee_id; + set date_of_birth = to_date( + co_dob_str default null on conversion error + ,'FXYYYY-MM-DD' -- NOSONAR G-1050 must be a literal + ) + where employee_id = co_employee_id; end set_dob; end employee_api; / From 590579b97efb7a41b0297898f6a8911ed5a652f7 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 1 Sep 2023 12:36:38 +0200 Subject: [PATCH 61/63] Fix violations of G-9030 --- docs/4-language-usage/9-function-usage/g-9020.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/4-language-usage/9-function-usage/g-9020.md b/docs/4-language-usage/9-function-usage/g-9020.md index 1b54b44c..416465e9 100644 --- a/docs/4-language-usage/9-function-usage/g-9020.md +++ b/docs/4-language-usage/9-function-usage/g-9020.md @@ -21,7 +21,7 @@ create or replace package body employee_api is co_salary constant type_up.date_string := in_salary; begin update employees - set salary = to_number(co_salary) -- violates also G-9030 + set salary = to_number(co_salary default null on conversion error) where employee_id = co_employee_id; end set_dob; end employee_api; From 35b160a7ba80dfee80274dc1387c9f58206d6212 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 1 Sep 2023 12:38:37 +0200 Subject: [PATCH 62/63] consistent style of NOSONAR marker --- docs/4-language-usage/9-function-usage/g-9010.md | 2 +- docs/4-language-usage/9-function-usage/g-9020.md | 4 ++-- docs/4-language-usage/9-function-usage/g-9030.md | 4 ++-- docs/4-language-usage/9-function-usage/g-9040.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/4-language-usage/9-function-usage/g-9010.md b/docs/4-language-usage/9-function-usage/g-9010.md index ecdfbc12..7ee371c6 100644 --- a/docs/4-language-usage/9-function-usage/g-9010.md +++ b/docs/4-language-usage/9-function-usage/g-9010.md @@ -40,7 +40,7 @@ create or replace package body employee_api is co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(co_dob_str default null on conversion error,'FXYYYY-MM-DD') -- NOSONAR G-1050 must be a literal + set date_of_birth = to_date(co_dob_str default null on conversion error,'FXYYYY-MM-DD') -- NOSONAR: G-1050 must be a literal where employee_id = co_employee_id; end set_dob; end employee_api; diff --git a/docs/4-language-usage/9-function-usage/g-9020.md b/docs/4-language-usage/9-function-usage/g-9020.md index 416465e9..29645077 100644 --- a/docs/4-language-usage/9-function-usage/g-9020.md +++ b/docs/4-language-usage/9-function-usage/g-9020.md @@ -42,8 +42,8 @@ create or replace package body employee_api is update employees set salary = to_number( co_salary default null on conversion error - ,'99999999999999999999.99999' -- NOSONAR G-1050 must be a literal - ,q'[nls_numeric_characters='.,']' -- NOSONAR G-1050 must be a literal + ,'99999999999999999999.99999' -- NOSONAR: G-1050 must be a literal + ,q'[nls_numeric_characters='.,']' -- NOSONAR: G-1050 must be a literal ) where employee_id = co_employee_id; end set_dob; diff --git a/docs/4-language-usage/9-function-usage/g-9030.md b/docs/4-language-usage/9-function-usage/g-9030.md index 6057ac23..0ba0404c 100644 --- a/docs/4-language-usage/9-function-usage/g-9030.md +++ b/docs/4-language-usage/9-function-usage/g-9030.md @@ -23,7 +23,7 @@ create or replace package body employee_api is co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(co_dob_str,'FXYYYY-MM-DD' -- NOSONAR G-1050 must be a literal + set date_of_birth = to_date(co_dob_str,'FXYYYY-MM-DD' -- NOSONAR: G-1050 must be a literal ) where employee_id = co_employee_id; end set_dob; @@ -45,7 +45,7 @@ create or replace package body employee_api is update employees set date_of_birth = to_date( co_dob_str default null on conversion error - ,'FXYYYY-MM-DD' -- NOSONAR G-1050 must be a literal + ,'FXYYYY-MM-DD' -- NOSONAR: G-1050 must be a literal ) where employee_id = co_employee_id; end set_dob; diff --git a/docs/4-language-usage/9-function-usage/g-9040.md b/docs/4-language-usage/9-function-usage/g-9040.md index 20ba8b99..557c5647 100644 --- a/docs/4-language-usage/9-function-usage/g-9040.md +++ b/docs/4-language-usage/9-function-usage/g-9040.md @@ -47,7 +47,7 @@ create or replace package body employee_api is update employees set date_of_birth = to_date( co_dob_str default null on conversion error - ,'FXYYYY-MM-DD' -- NOSONAR G-1050 must be a literal + ,'FXYYYY-MM-DD' -- NOSONAR: G-1050 must be a literal ) where employee_id = co_employee_id; end set_dob; From 8877f3ffac3bb02be7bf6a3d8ba0508a1d89f68f Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 1 Sep 2023 12:45:21 +0200 Subject: [PATCH 63/63] Fix violation of G-9030 --- docs/4-language-usage/9-function-usage/g-9010.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/4-language-usage/9-function-usage/g-9010.md b/docs/4-language-usage/9-function-usage/g-9010.md index 7ee371c6..fddffeb7 100644 --- a/docs/4-language-usage/9-function-usage/g-9010.md +++ b/docs/4-language-usage/9-function-usage/g-9010.md @@ -21,7 +21,7 @@ create or replace package body employee_api is co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(co_dob_str) -- violates also G-9030 + set date_of_birth = to_date(co_dob_str default null on conversion error) where employee_id = co_employee_id; end set_dob; end employee_api; @@ -40,7 +40,10 @@ create or replace package body employee_api is co_dob_str constant type_up.date_string := in_dob_str; begin update employees - set date_of_birth = to_date(co_dob_str default null on conversion error,'FXYYYY-MM-DD') -- NOSONAR: G-1050 must be a literal + set date_of_birth = to_date( + co_dob_str default null on conversion error + ,'FXYYYY-MM-DD' -- NOSONAR: G-1050 must be a literal + ) where employee_id = co_employee_id; end set_dob; end employee_api;