请问这个存储过程中的变量V_CREATER作为where条件的一部分时可以编译通过,不会被被当成表中的字段?

时间:2023-01-21 19:11:03
请问这个存储过程中的变量V_CREATER作为where条件的一部分时可以编译通过,不会被被当成表中的字段?
如果说where条件是WHERE CF.NOTE='TEST' AND CF.CREATER='张三',我们都能理解,这个条件的意思是查询表中NOTE字段的值是'TEST' 并且CREATER字段的值是'张三'的数据。
但是下面这种是读取json字符串中的CREATER,将V_CREATER赋值给变量V_CREATER,那么这个变量V_CREATER为什么没有被当做表中的字段在where中被执行?
WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER),这个意思是当变量V_CREATER 不为空时那么将V_CREATER 的值作为where条件的一部分,若V_CREATER 为空则相当于没有这个条件,
那么V_CREATER IS NULL OR CF.CREATER=V_CREATER被解释成什么了?
最终是变成了如果V_CREATER 是空,那么WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER')这句话是变成了WHERE CF.NOTE='TEST' AND ( 1=1 OR CF.CREATER=V_CREATER)还是变成了
WHERE CF.NOTE='TEST' AND ( true OR CF.CREATER=V_CREATER)还是变成了别的什么?很不理解这块的意思。
如果V_CREATER 不为空的情况下WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)就可以变成WHERE CF.NOTE='TEST' AND (CF.CREATER=V_CREATER)这句与WHERE CF.NOTE='TEST' AND CF.CREATER='张三'是差不多的效果可以理解,那么V_CREATER 不为空的情况下WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)变成了WHERE CF.NOTE='TEST' AND ( 1=0 OR CF.CREATER=V_CREATER)
还是变成了WHERE CF.NOTE='TEST' AND ( false OR CF.CREATER=V_CREATER)?
存储过程代码如下:
CREATE OR REPLACE 
PROCEDURE TEST  (
V_IN_JSON  IN  CLOB,
V_OU_JSON   OUT SYS_REFCURSOR  
)
IS
V_CREATER VARCHAR2(50);
V_CREATE_DATE_BEGIN VARCHAR2(100);
BEGIN
BEGIN
    FOR V_REC IN (
                  SELECT * FROM JSON_TABLE(V_IN_JSON, '$.condition[*]'
                          COLUMNS
                          cFieldName VARCHAR2(100) PATH '$.cFieldName',
  ConValue VARCHAR2(100) PATH '$.ConValue'
                                    )
                 ) LOOP
      IF V_REC.cFieldName = 'CREATER'
        THEN
          V_CREATER := V_REC.ConValue;
  ELSIF V_REC.cFieldName = 'CREATE_DATE'
        THEN
          V_CREATE_DATE_BEGIN := V_REC.ConValue;
      END IF;
    END LOOP;
END;
 
OPEN V_OU_JSON FOR
SELECT 
CF.NOTE,
CF.PMT_AMOUNT,
CF.CREATE_DATE,
CF.CREATER,
CF.MODIFY_DATE
FROM   tableCF CF
CF.MODIFIER
WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER='V_CREATER')
RETURN;

END TEST;

7 个解决方案

#1


        WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER='V_CREATER')


V_CREATER ,这里只是被当做一个常量。

#2


CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)

#3


SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                    20
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
      7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
      7839 KING       PRESIDENT            17-11月-81           5000                    10
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
      7900 JAMES      CLERK           7698 03-12月-81            950                    30
      7902 FORD       ANALYST         7566 03-12月-81           3000                    20
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

已选择14行。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  5  dbms_output.put_line('v_temp='||v_temp);
  6  end;
  7  /
v_temp=1

PL/SQL 过程已成功完成。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  v_empno:=7369;
  5  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  6  dbms_output.put_line('v_temp='||v_temp);
  7  end;
  8  /
v_temp=0

#4


引用 1 楼 wmxcn2000 的回复:
        WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER='V_CREATER')


V_CREATER ,这里只是被当做一个常量。

如果V_CREATER 是空,那么WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER')这句话是变成了WHERE CF.NOTE='TEST' AND ( 1=1 OR CF.CREATER=V_CREATER)还是变成了
WHERE CF.NOTE='TEST' AND ( true OR CF.CREATER=V_CREATER)还是变成了别的什么?很不理解这块的意思。
如果V_CREATER 不为空的情况下WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)就可以变成WHERE CF.NOTE='TEST' AND (CF.CREATER=V_CREATER)这句与WHERE CF.NOTE='TEST' AND CF.CREATER='张三'是差不多的效果可以理解,那么V_CREATER 不为空的情况下WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)变成了WHERE CF.NOTE='TEST' AND ( 1=0 OR CF.CREATER=V_CREATER)
还是变成了WHERE CF.NOTE='TEST' AND ( false OR CF.CREATER=V_CREATER)?

#5


引用 3 楼 sych888 的回复:
SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                    20
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
      7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
      7839 KING       PRESIDENT            17-11月-81           5000                    10
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
      7900 JAMES      CLERK           7698 03-12月-81            950                    30
      7902 FORD       ANALYST         7566 03-12月-81           3000                    20
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

已选择14行。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  5  dbms_output.put_line('v_temp='||v_temp);
  6  end;
  7  /
v_temp=1

PL/SQL 过程已成功完成。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  v_empno:=7369;
  5  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  6  dbms_output.put_line('v_temp='||v_temp);
  7  end;
  8  /
v_temp=0

您好,您这里的v_empno 如果为空的话, select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);是否会变成 select count(*) into v_temp from emp e where e.ename='JAMES' and  1=1这种形式;?

#6


where CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)
首先注意括号里面是or
拆分开 就变成了
where CF.NOTE='TEST'  and v_creater is null 
or  
where where CF.NOTE='TEST'  and cf.creater=v_creater 
满足or的任何一种情况就可以了。

#7


引用 5 楼 xianying7509 的回复:
Quote: 引用 3 楼 sych888 的回复:

SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                    20
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
      7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
      7839 KING       PRESIDENT            17-11月-81           5000                    10
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
      7900 JAMES      CLERK           7698 03-12月-81            950                    30
      7902 FORD       ANALYST         7566 03-12月-81           3000                    20
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

已选择14行。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  5  dbms_output.put_line('v_temp='||v_temp);
  6  end;
  7  /
v_temp=1

PL/SQL 过程已成功完成。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  v_empno:=7369;
  5  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  6  dbms_output.put_line('v_temp='||v_temp);
  7  end;
  8  /
v_temp=0

您好,您这里的v_empno 如果为空的话, select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);是否会变成 select count(*) into v_temp from emp e where e.ename='JAMES' and  1=1这种形式;?

可以这么认为

#1


        WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER='V_CREATER')


V_CREATER ,这里只是被当做一个常量。

#2


CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)

#3


SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                    20
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
      7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
      7839 KING       PRESIDENT            17-11月-81           5000                    10
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
      7900 JAMES      CLERK           7698 03-12月-81            950                    30
      7902 FORD       ANALYST         7566 03-12月-81           3000                    20
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

已选择14行。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  5  dbms_output.put_line('v_temp='||v_temp);
  6  end;
  7  /
v_temp=1

PL/SQL 过程已成功完成。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  v_empno:=7369;
  5  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  6  dbms_output.put_line('v_temp='||v_temp);
  7  end;
  8  /
v_temp=0

#4


引用 1 楼 wmxcn2000 的回复:
        WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER='V_CREATER')


V_CREATER ,这里只是被当做一个常量。

如果V_CREATER 是空,那么WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER')这句话是变成了WHERE CF.NOTE='TEST' AND ( 1=1 OR CF.CREATER=V_CREATER)还是变成了
WHERE CF.NOTE='TEST' AND ( true OR CF.CREATER=V_CREATER)还是变成了别的什么?很不理解这块的意思。
如果V_CREATER 不为空的情况下WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)就可以变成WHERE CF.NOTE='TEST' AND (CF.CREATER=V_CREATER)这句与WHERE CF.NOTE='TEST' AND CF.CREATER='张三'是差不多的效果可以理解,那么V_CREATER 不为空的情况下WHERE CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)变成了WHERE CF.NOTE='TEST' AND ( 1=0 OR CF.CREATER=V_CREATER)
还是变成了WHERE CF.NOTE='TEST' AND ( false OR CF.CREATER=V_CREATER)?

#5


引用 3 楼 sych888 的回复:
SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                    20
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
      7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
      7839 KING       PRESIDENT            17-11月-81           5000                    10
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
      7900 JAMES      CLERK           7698 03-12月-81            950                    30
      7902 FORD       ANALYST         7566 03-12月-81           3000                    20
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

已选择14行。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  5  dbms_output.put_line('v_temp='||v_temp);
  6  end;
  7  /
v_temp=1

PL/SQL 过程已成功完成。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  v_empno:=7369;
  5  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  6  dbms_output.put_line('v_temp='||v_temp);
  7  end;
  8  /
v_temp=0

您好,您这里的v_empno 如果为空的话, select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);是否会变成 select count(*) into v_temp from emp e where e.ename='JAMES' and  1=1这种形式;?

#6


where CF.NOTE='TEST' AND (V_CREATER IS NULL OR CF.CREATER=V_CREATER)
首先注意括号里面是or
拆分开 就变成了
where CF.NOTE='TEST'  and v_creater is null 
or  
where where CF.NOTE='TEST'  and cf.creater=v_creater 
满足or的任何一种情况就可以了。

#7


引用 5 楼 xianying7509 的回复:
Quote: 引用 3 楼 sych888 的回复:

SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                    20
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
      7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
      7839 KING       PRESIDENT            17-11月-81           5000                    10
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
      7900 JAMES      CLERK           7698 03-12月-81            950                    30
      7902 FORD       ANALYST         7566 03-12月-81           3000                    20
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

已选择14行。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  5  dbms_output.put_line('v_temp='||v_temp);
  6  end;
  7  /
v_temp=1

PL/SQL 过程已成功完成。

SQL> declare v_empno number;
  2  v_temp number;
  3  begin
  4  v_empno:=7369;
  5  select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);
  6  dbms_output.put_line('v_temp='||v_temp);
  7  end;
  8  /
v_temp=0

您好,您这里的v_empno 如果为空的话, select count(*) into v_temp from emp e where e.ename='JAMES' and (v_empno is null or e.empno=v_empno);是否会变成 select count(*) into v_temp from emp e where e.ename='JAMES' and  1=1这种形式;?

可以这么认为