Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Rule: never use multiple UPDATE OF in trigger event clause #27

Closed
silviomarghitola opened this issue Jun 3, 2019 · 2 comments · Fixed by #86
Closed

New Rule: never use multiple UPDATE OF in trigger event clause #27

silviomarghitola opened this issue Jun 3, 2019 · 2 comments · Fixed by #86
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@silviomarghitola
Copy link

Language Usage / Stored Objects / Triggers
Never use multiple UPDATE OF statements in the event clause of a trigger

bad:
CREATE OR REPLACE TRIGGER xyz BEFORE UPDATE OF column1 OR UPDATE OF column2 ...

good:
CREATE OR REPLACE TRIGGER xyz BEFORE UPDATE OF column1, column2 ...

@PhilippSalvisberg
Copy link
Collaborator

from SonarSource:

The DML events clause of a trigger is not meant to be used with multiple OF conditions. When it is, only the last one will actually be taken into account, without any error message being produced. This can lead to counter-intuitive code.

Only the UPDATE event should have an OF condition, and there should be at most one occurence of it.

Noncompliant Code Example

CREATE OR REPLACE TRIGGER myTrigger
  BEFORE UPDATE OF firstName OR UPDATE OF lastName -- Noncompliant - will *only* be triggered on updates of lastName!
  ON myTable
  FOR EACH ROW
BEGIN
  NULL;
END;
/

Compliant Solution

CREATE OR REPLACE TRIGGER myTrigger
  BEFORE UPDATE OF firstName, lastName             -- Compliant - triggered on updates of firstName or/and lastName
  ON myTable
  FOR EACH ROW
BEGIN
  NULL;
END;
/

@PhilippSalvisberg PhilippSalvisberg added enhancement New feature or request help wanted Extra attention is needed labels Jun 4, 2019
@PhilippSalvisberg
Copy link
Collaborator

I ran the following test in a 19c Database instance:

REATE OR REPLACE TRIGGER emp_trg
  BEFORE UPDATE OF ename OR UPDATE OF job 
  ON emp
  FOR EACH ROW
BEGIN
  :new.sal := :old.sal*2;
END;
/

set echo on
select * from emp where empno = 7788;
update emp set ename = 'hallo' where empno = 7788;
select * from emp where empno = 7788;
rollback;
select * from emp where empno = 7788;
update emp set job = 'hallo' where empno = 7788;
select * from emp where empno = 7788;
rollback;
select * from emp where empno = 7788;

the result (console output) was:

SQL> set echo on
SQL> select * from emp where empno = 7788;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7788 SCOTT      ANALYST         7566 19.04.1987 00:00:00       3000                    20

SQL> update emp set ename = 'hallo' where empno = 7788;

1 row updated.

SQL> select * from emp where empno = 7788;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7788 hallo      ANALYST         7566 19.04.1987 00:00:00       3000                    20

SQL> rollback;

Rollback complete.

SQL> select * from emp where empno = 7788;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7788 SCOTT      ANALYST         7566 19.04.1987 00:00:00       3000                    20

SQL> update emp set job = 'hallo' where empno = 7788;

1 row updated.

SQL> select * from emp where empno = 7788;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7788 SCOTT      hallo           7566 19.04.1987 00:00:00       6000                    20

SQL> rollback;

Rollback complete.

SQL> select * from emp where empno = 7788;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7788 SCOTT      ANALYST         7566 19.04.1987 00:00:00       3000                    20

Hence, this rule makes really sense.

@PhilippSalvisberg PhilippSalvisberg removed the help wanted Extra attention is needed label Jun 4, 2019
@PhilippSalvisberg PhilippSalvisberg added this to the v4.0 milestone Jun 4, 2019
@kibeha kibeha self-assigned this Sep 2, 2020
kibeha added a commit to kibeha/plsql-and-sql-coding-guidelines that referenced this issue Sep 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants