比较SQL中的月份和年份

时间:2014-12-18 19:08:34

标签: sql oracle datetime

我想将表格中的月份和年份列与我用来放置此表达式的用户提供的月份和年份参数进行比较

 select  ca_expense_mst.trans_id, trans_no
 from ca_expense_mst , CA_EXPENSE_FINANCE_DTL fndDtl     
 where  ca_expense_mst.TRANS_ID=fndDtl.TRANS_ID    
 and TO_DATE(''|| fndDtl.year ||'/'|| fndDtl.month || '/01', 'yyyy/mm/dd')  between  TO_DATE(''|| :fromYear ||'/'|| :fromMonth || '/01', 'yyyy/mm/dd')  and TO_DATE(''|| :toYear ||'/'|| :toMonth || '/01', 'yyyy/mm/dd')     
 and  fndDtl.account_id= nvl(to_number(:account_no),fndDtl.account_id)

它工作正常,但如果我添加聚合函数count(),我会得到这个例外:

  

产生的原因:java.sql.SQLDataException:ORA-01841:(全)年份必须-4713和9999之间,并且不能为0

我需要一种方法,以便我可以将月份和年份列与月份和年份参数进行比较

这是抛出异常的SQL:

select  count(ca_expense_mst.trans_id)  as all_trans
from ca_expense_mst , CA_EXPENSE_FINANCE_DTL fndDtl     
where  ca_expense_mst.TRANS_ID=fndDtl.TRANS_ID    
and TO_DATE(''|| fndDtl.year ||'/'|| fndDtl.month || '/01', 'yyyy/mm/dd')  between  TO_DATE(''|| 
:fromYear ||'/'|| :fromMonth || '/01', 'yyyy/mm/dd')  and TO_DATE(''|| :toYear ||'/'|| :toMonth || '/01', 'yyyy/mm/dd') 
and  fndDtl.account_id= nvl(to_number(:account_no),fndDtl.account_id)

这是我表格的脚本

CREATE TABLE SAS_ADF.CA_EXPENSE_FINANCE_DTL
(
  EXP_FIN_ID          NUMBER,
  ACCOUNT_ID          NUMBER,
  TRANS_ID            NUMBER,
  AMOUNT_BY_CD        NUMBER,
  DEBIT_CREDIT        VARCHAR2(2 BYTE),
  CHEQUE_STATUS       VARCHAR2(20 BYTE),
  REFERENCE_NO        VARCHAR2(500 BYTE),
  REFERENCE_DATE      DATE,
  ENT_BY              VARCHAR2(50 BYTE),
  ENT_DATE            DATE,
  MODIFY_BY           VARCHAR2(50 BYTE),
  MODIFY_DATE         DATE,
  REFUND_TYPE_ID      NUMBER,
  STUDENT_ID          NUMBER,
  STD_FIN_APP_FLAG    VARCHAR2(2 BYTE),
  STD_AUDIT_APP_FLAG  VARCHAR2(2 BYTE),
  ACTION_DATE         DATE,
  MONTH               NUMBER,
  YEAR                NUMBER,
  CANCEL_FLAG         VARCHAR2(2 BYTE),
  EXP_FIN_ID_M        NUMBER,
  USER_TRANS_ID       VARCHAR2(500 BYTE),
  OLD_STUDENT_ID      NUMBER,
  CD                  VARCHAR2(10 BYTE),
  CURRENCY_RATE       NUMBER,
  AMOUNT_BY_CD_L      NUMBER,
  CURR_ISO            VARCHAR2(4 BYTE),
  STDUENT_ID_W        NUMBER,
  AMOUNT_BY_CD_C      NUMBER,
  DEBIT_CREDIT_C      VARCHAR2(10 BYTE)
)

这里是一些数据的屏幕截图

enter image description here

2 个答案:

答案 0 :(得分:4)

fndDtl.year中有一个NULL值。

以某种方式违反直觉,这会使您的格式ORA-01841: (full) year must be between -4713 and +9999, and not be 0提升:

select TO_DATE(''|| NULL ||'/'|| 12 || '/01', 'yyyy/mm/dd') from dual;
     

ORA-01841 :(完整)年份必须介于-4713和+9999之间,而不是0


事实上,您可以追踪到这种简单情况下的行为:

select TO_DATE('/', 'yyyy/') from dual
     

ORA-01841 :(完整)年份必须介于-4713和+9999之间,而不是0

然而,正如所注意到的那样现在在上面的评论中:

select TO_DATE('/', 'syyyy/') from dual
     

ORA-01858:找到一个非数字字符,其中包含数字

答案 1 :(得分:0)

从年份和月份中排除空值

select CA_EXPENSE_MST.TRANS_ID,
       TRANS_NO
  from CA_EXPENSE_MST
 inner join CA_EXPENSE_FINANCE_DTL FNDDTL on CA_EXPENSE_MST.TRANS_ID = FNDDTL.TRANS_ID
 where CA_EXPENSE_MST.TRANS_ID is not null
   and FNDDTL.YEAR is not null
   and FNDDTL.MONTH is not null
   and FNDDTL.ACCOUNT_ID = NVL(TO_NUMBER(:ACCOUNT_NO), FNDDTL.ACCOUNT_ID)
   and TO_DATE(FNDDTL.YEAR || '/' || FNDDTL.MONTH || '/01', 'yyyy/mm/dd') between TO_DATE(:FROMYEAR || '/' || :FROMMONTH || '/01', 'yyyy/mm/dd') and
       TO_DATE(:TOYEAR || '/' || :TOMONTH || '/01', 'yyyy/mm/dd');

以下是链接:sqlFiddle