在 Oracle SQL 中未获得预期结果

Not getting expected results in Oracle SQL

我有一个带有 5 个提示的查询

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

我的查询的问题是它不遵循下面给出的标准的结果:

  1. 没有强制性提示,因此如果报告 运行 所有条件均为空白,则会发生以下情况:
    • 无论何时创建,都会显示所有未完成/正在处理清单的学生。
    • 将显示在当前学期内完成核对清单的所有学生。
  2. 如果指定了(过去的)录取期限,e-i 中的案例将显示指定期限的完整清单。
  3. 如果指定了(过去的)录取期限,则只会显示在该期限内创建但仍未完成/正在进行的清单的清单。
  4. 如果指定了未来的录取期限,则只会显示当前未完成/进行中的清单。

这里是 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 的部分。中间的大部分部分在给定条件下都可以正常工作。我做错了什么吗?特别是在第一部分,我认为应该很容易将该提示的所有值提取为默认值。

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

谢谢!

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

所以首先,decode 这些天不受欢迎,原因有几个。而不是例如

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

我愿意

EMPLID LIKE NVL(:1, '%')

其次,这可能是给您带来麻烦的部分,这些行没有按照您的要求进行:

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

第二行永远不会是真的。任何与 null 的比较都将为 null,而不是 true。所以 '' = '' 将 return 为空,不正确。为了清楚起见,通常认为将括号与 AND/OR 混合使用是一种很好的做法。所以相反,我会做这样的事情:

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