在Oracle SQL中没有得到预期的结果

时间:2018-04-11 17:00:41

标签: sql oracle peoplesoft

我有5个提示的​​查询

:1 - EMPLID
:2 - APPL_NBR
:3 - CHECKLIST_CD
:4 - CHECKLIST STATUS
:5 - ADMIT_TERM

我的查询存在的问题是它不符合下面给出的条件的结果:

  1. 没有强制性提示,因此如果在所有条件为空的情况下运行报告,则会发生以下情况:
    • 所有具有不完整/正在进行的核对清单的学生将被显示,无论他们何时被创建。
    • 将显示所有在当前学期内完成核对清单的学生。
  2. 如果指定了(过去)承认条款,则e-i的案例将显示指定期限的完整清单。
  3. 如果指定了(过去)承认条款,则只会显示在该期间创建的仍未完成/正在进行中的核对清单。
  4. 如果指定了未来的承认条款,则仅显示当前未完成/正在进行的核对清单。
  5. 这是sql:

    SELECT A.EMPLID, A.NAME, A.ADM_APPL_NBR, A.ADMIN_FUNCTION, A.STDNT_CAR_NBR, 
    A.ACAD_CAREER, A.APPL_PROG_NBR, A.ADMIT_TERM, A.CHECKLIST_CD, A.DESCRSHORT, 
    A.CHECKLIST_STATUS, TO_CHAR(A.STATUS_DT,'YYYY-MM-DD'), 
    TO_CHAR(A.DUE_DT,'YYYY-MM-DD'), A.COMM_COMMENTS, A.SEQ_3C, A.CHKLST_ITEM_CD, 
    A.DESCR, A.ITEM_STATUS, TO_CHAR(A.UM_STATUS_DT_CL,'YYYY-MM-DD'), 
    TO_CHAR(A.UM_DUE_DT_CL,'YYYY-MM-DD'), A.RESPONSIBLE_ID 
    FROM PS_UM_7902_VW2 A 
    
    --for Condition 1, for prompts with no values provided
    WHERE ( 1 = 1 AND EMPLID LIKE DECODE (:1, '', '%', :1) 
     AND ADM_APPL_NBR LIKE DECODE(:2, '', '%', :2) 
     AND CHECKLIST_CD LIKE DECODE(:3, '', '%', :3) 
     AND A.CHECKLIST_STATUS = :4 
     OR '' = :4 
     AND A.CHECKLIST_STATUS = 'I' 
     OR ( A.CHECKLIST_STATUS = 'C' 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT) 
     AND ( A.ADMIT_TERM = A.STRM 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT) 
     -- end for Condition 1
    
     OR A.EMPLID = :1 
     AND ( 1 = 1 AND ADM_APPL_NBR LIKE DECODE(:2, '', '%', :2) 
     AND CHECKLIST_CD LIKE DECODE(:3, '', '%', :3) 
     AND A.CHECKLIST_STATUS = 'I' 
     OR ( A.CHECKLIST_STATUS = 'C' 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT) 
     AND ( A.ADMIT_TERM = A.STRM 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT)) 
     OR A.ADM_APPL_NBR = :2 
     AND ( 1 = 1 AND EMPLID LIKE DECODE (:1, '', '%', :1) 
     AND CHECKLIST_CD LIKE DECODE(:3, '', '%', :3) 
     AND A.CHECKLIST_STATUS = 'I' 
     OR ( A.CHECKLIST_STATUS = 'C' 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT) 
     AND ( A.ADMIT_TERM = A.STRM 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT)) 
     OR A.CHECKLIST_CD = :3 
     AND ( 1 = 1 AND EMPLID LIKE DECODE (:1, '', '%', :1) 
     AND ADM_APPL_NBR LIKE DECODE(:2, '', '%', :2) 
     AND A.CHECKLIST_STATUS = 'I' 
     OR ( A.CHECKLIST_STATUS = 'C' 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT) 
     AND ( A.ADMIT_TERM = A.STRM 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT)) 
     OR A.CHECKLIST_STATUS = :4 
     AND ( 1 = 1 AND EMPLID LIKE DECODE (:1, '', '%', :1) 
     AND ADM_APPL_NBR LIKE DECODE(:2, '', '%', :2) 
     AND CHECKLIST_CD LIKE DECODE(:3, '', '%', :3)) 
     OR ( A.CHECKLIST_STATUS = 'C' 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT) 
     AND ( A.ADMIT_TERM = A.STRM 
     AND SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT) 
    
     --for Conditions 2, 3 and 4 for ADMIT_TERM
     OR A.ADMIT_TERM = :5 
     AND 1 = 1 AND EMPLID LIKE DECODE (:1, '', '%', :1) 
     AND ADM_APPL_NBR LIKE DECODE(:2, '', '%', :2) 
     AND CHECKLIST_CD LIKE DECODE(:3, '', '%', :3) 
     AND (( SYSDATE > A.TERM_END_DT 
     AND A.CHECKLIST_STATUS = 'C') 
     OR SYSDATE BETWEEN A.TERM_BEGIN_DT AND A.TERM_END_DT) 
     AND ( A.CHECKLIST_STATUS = 'I' 
     OR ( SYSDATE < A.TERM_BEGIN_DT 
     AND A.CHECKLIST_STATUS = 'I')));
     -- end for Conditions 2, 3 and 4
    

    我已经分离了我做条件1,2,3和4的部分。中间的大多数部件在给定条件下工作正常。我做错了什么吗?特别是在第一部分,我认为应该很容易将该提示的所有值拉为默认值。

    感谢我能得到的所有帮助。

    谢谢!

1 个答案:

答案 0 :(得分:4)

我认为您的主要问题是使用''来表示null。我建议不这样做,因为其他语言对待空字符串的方式与SQL不同。

首先,由于几个原因,decode在这些日子里感到不满。而不是例如

EMPLID LIKE DECODE (:1, '', '%', :1) 

我只是做

EMPLID LIKE NVL(:1, '%')

其次,这可能是给你带来麻烦的部分,这些行没有做你想做的事情:

AND A.CHECKLIST_STATUS = :4 
OR '' = :4 

第二行永远不会成真。与null的任何比较都将为null,而不是true。所以'' = ''将返回null,而不是true。为清晰起见,通常认为使用带有混合AND / OR的括号是一种好习惯。所以相反,我会做这样的事情:

AND (A.CHECKLIST_STATUS = :4 OR :4 is null)