Oracle NVL和DECODE函数的漏洞

  在Oracle中,即使条件不符合, NVL函数也会执行条件不符合的选项,对于DECODE函数,如果里面有自定义函数,则decode不会执行不符合条件的函数,但是如果decode里面有sequence.nextval,不管条件是否符合,sequence都会自增。

 1 --创建一个函数,当被调用时打印“the functionss is executed”
 2 CREATE OR REPLACE FUNCTION f_print_str
 3 RETURN NUMBER
 4  AS
 5 BEGIN
 6 
 7   DBMS_OUTPUT.PUT_LINE('the funcionts is executed');
 8   RETURN 1;
 9 
10 END f_print_str;

NVL:

  比如下面的例子,即使nvl第一个参数不为空,返回第一个参数的值-11,但是函数f_print_str还是会被执行,打印"the function is eceucted"

 1 SQL> set serveroutput on
 2 SQL> select nvl('11',f_print_str) from dual;
 3  
 4 NVL('11',F_PRINT_STR)
 5 ----------------------------------------
 6 11
 7  
 8 the funcionts is executed
 9  
10 SQL> 

DECODE:

decode函数不会执行不符合条件的选项,下面的例子没有打印“the functions is exeucted”

1 SQL> set serveroutput on
2 SQL> select decode('10','10','is same',f_print_str) from dual;
3  
4 DECODE('10','10','ISSAME',F_PR
5 ----------------------------------------
6 is same
7  
8 SQL> 

如果decode函数里面包含sequence.nextval,则不管条件是否符合,sequence值都会变化。

 1 SQL> CREATE SEQUENCE SEQ_TEST MINVALUE 1 MAXVALUE 200 START WITH 1 INCREMENT BY 1 NOCYCLE NOCACHE;
 2  
 3 Sequence created
 4  
 5 SQL> select seq_test.nextval from dual;
 6  
 7    NEXTVAL
 8 ----------
 9          1
10  
11 SQL> select decode('10','10','is same',seq_test.nextval) from dual; --此处sequence条件不成立,但是也被执行
12  
13 DECODE('10','10','ISSAME',SEQ_
14 ----------------------------------------
15 is same
16  
17 SQL> select seq_test.currval from dual;
18  
19    CURRVAL
20 ----------
21          2
22  
23 SQL> 

为了解决上面的问题,可以创建一个函数用于返回sequence.nextval的值,如果条件不成立,sequence的值不会变动。

1 --创建一个函数,用于返回sequence.nextval的值
2 CREATE OR REPLACE FUNCTION F_GET_SEQ RETURN NUMBER AS
3   V_SEQ_NUM NUMBER;
4 BEGIN
5   SELECT SEQ_TEST.NEXTVAL INTO V_SEQ_NUM FROM DUAL;
6   DBMS_OUTPUT.PUT_LINE('the funcionts is executed');
7   RETURN V_SEQ_NUM;
8 
9 END F_GET_SEQ;

比如下面的例子,f_get_seq处条件不成立,函数f_get_seq不会执行,相应的里面的sequence:seq_test的值也不会有变动

 1 SQL> set serveroutput on
 2 SQL> select seq_test.currval from dual;
 3  
 4    CURRVAL
 5 ----------
 6          3
 7  
 8 SQL> select decode('10','10','is same',f_get_seq) from dual;
 9  
10 DECODE('10','10','ISSAME',F_GE
11 ----------------------------------------
12 is same
13  
14 SQL> select seq_test.currval from dual;
15  
16    CURRVAL
17 ----------
18          3
19  
20 SQL> 
原文地址:https://www.cnblogs.com/summerlife/p/3950998.html