在Oracle中减去日期

时间:2018-04-27 22:08:59

标签: sql oracle oracle11g

今天在Oracle中使用日期,使用以下查询执行日期减法:

SELECT TO_DATE(SYSDATE, 'DD/MM/YYYY') AS HOY, 
      TO_DATE(T.FECHAEVAL, 'DD/MM/YYYY') AS FECHA, 
      TO_DATE(SYSDATE, 'DD/MM/YYYY') - TO_DATE(T.FECHAEVAL, 'DD/MM/YYYY') AS RESTA 
FROM HP_TRANSACT_RES_EVAL_HIPO t
WHERE T.FECHAEVAL IS NOT NULL

我抛出以下结果:

enter image description here

正如你所看到的,减法给我带来了负面结果,当然它们不是预期的,因此测试做了以下查询:

SELECT TO_DATE(SYSDATE, 'DD/MM/YYYY') AS HOY, 
       TO_DATE(T.FECHAEVAL, 'DD/MM/YYYY') AS FECHA, 
       TO_DATE(SYSDATE) - TO_DATE(T.FECHAEVAL, 'DD/MM/YYYY') AS RESTA 
FROM HP_TRANSACT_RES_EVAL_HIPO t
WHERE T.FECHAEVAL IS NOT NULL

我抛出以下结果:

enter image description here

这些是预期的结果。在这里,我的问题是,将以下方式TO_DATE (SYSDATE, 'DD / MM / YYYY') - TO_DATE (T.FECHAEVAL, 'DD / MM / YYYY')减去与我投掷正确结果TO_DATE (SYSDATE) - TO_DATE (T.FECHAEVAL, 'DD / MM / YYYY')的方式之间有什么区别?

当您注意到字段T.FECHAEVALVARCHAR2时。

1 个答案:

答案 0 :(得分:1)

您似乎是选择将日期值存储到VARCHAR2列的大量用户的一部分;像往常一样,这是一个坏主意 - 如果可能的话,改变它。

这是一个展示你应该做的事情的例子:

SQL> create table hp_transact_res_Eval_hipo (fechaeval varchar2(20));

Table created.

SQL> insert into hp_transact_res_Eval_hipo
  2    select '13/05/2009' from dual union
  3    select '14/05/2009' from dual union
  4    select '08/05/2009' from dual union
  5    select '23/07/2010' from dual union
  6    select '22/09/2010' from dual;

5 rows created.
  • TO_CHAR应用于SYSDATE(这是一个返回DATE数据类型值的函数),并使用适当的格式掩码将其显示为dd / mm / yyyy
  • 原样选择FECHAEVAL,因为您已经将其存储为dd / mm / yyyy,因此 - 将其转换为日期(TO_DATE无效)
  • 由于减去两个日期值会产生这两个值之间的天数,因此我将TRUNC函数应用于SYSDATE以便从中删除时间组件,并TO_DATE添加到{{ 1}}将其转换为日期。
FECHAEVAL

最后,向您展示为什么不应将日期值存储到SQL> select 2 to_char(sysdate, 'dd/mm/yyyy') as hoy, 3 fechaeval as fecha, 4 trunc(sysdate) - to_date(fechaeval, 'dd/mm/yyyy') as resta 5 from hp_transact_res_Eval_hipo; HOY FECHA RESTA ---------- -------------------- ---------- 28/04/2018 08/05/2009 3277 28/04/2018 13/05/2009 3272 28/04/2018 14/05/2009 3271 28/04/2018 22/09/2010 2775 28/04/2018 23/07/2010 2836 SQL> 列中:这是一个有效的字符串(并且可以插入到表中),但无效日期。减法 - 正如预期的那样 - 会导致错误:

VARCHAR2

如果有人输入与我类似的值,您将会遇到巨大的问题。再次:切换到SQL> insert into hp_transact_res_eval_hipo values ('33/44/5555'); 1 row created. SQL> select trunc(sysdate) - to_date(fechaeval, 'dd/mm/yyyy') as resta 2 from hp_transact_res_eval_hipo; ERROR: ORA-01847: day of month must be between 1 and last day of month no rows selected SQL> 数据类型列。