今天在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
我抛出以下结果:
正如你所看到的,减法给我带来了负面结果,当然它们不是预期的,因此测试做了以下查询:
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
我抛出以下结果:
这些是预期的结果。在这里,我的问题是,将以下方式TO_DATE (SYSDATE, 'DD / MM / YYYY') - TO_DATE (T.FECHAEVAL, 'DD / MM / YYYY')
减去与我投掷正确结果TO_DATE (SYSDATE) - TO_DATE (T.FECHAEVAL, 'DD / MM / YYYY')
的方式之间有什么区别?
当您注意到字段T.FECHAEVAL
为VARCHAR2
时。
答案 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>
数据类型列。