Oracle获取当前日期与时间戳之间插入的所有记录

时间:2020-06-24 20:04:51

标签: oracle date datetime select datetime-format

无法正确检索具有格式化日期值的记录,需要选择具有正确日期格式的查询以获取每天插入的所有记录

我的脚本中有一个这样的日期字符串-

dateString :='26-MAR-20 05.00.00.00000000 AM'; 

我想在此日期值上增加0.313分钟。我也想 将其增加到第二天,就像这样-'27 -MAR-20 05.00.00.00000000 AM';

我尝试过这个

dateString :='26-MAR-20 05.00.00.00000000 AM'; 
dateString :=to_char(dateField,'DD-MON-YYYY HH24:MI:SS.FF'); 
dateField := to_timestamp(dateString, 'DD/MON/YYYY HH24:MI:SS.FF') + 0.313 * INTERVAL '1' MINUTE;
​

我可以看到输出,并将这些值插入到数据库中,但是 无法使用这些格式化的日期值正确检索记录

我怀疑可能与时间戳字段有关

当我运行此查询时-

select *from rptallexceptions where exceptiontime between '27-MAR-2020 04.00.00.000000000 AM' and '28-MAR-2020 03.59.00.000000000 AM' order by exceptiontime desc;
​

---该记录有3833条记录,但预期为4600条

仅显示3月27日的记录,未检索到插入包含3月28日的时间戳的记录。

select *from rptallexceptions where exceptiontime between '28-MAR-2020 04.00.00.000000000 AM' and '29-MAR-2020 03.59.00.000000000 AM' order by exceptiontime desc; 

---此行返回“ 0”行

脚本摘录:

cnt :=cnt +1;
dateString :=to_char(dateField,'DD-MON-YYYY HH24:MI:SS.FF');
-- add time difference for each exception.
dateField := to_timestamp(dateString, 'DD/MON/YYYY HH24:MI:SS.FF') + 0.313 * INTERVAL '1' MINUTE; 
-- after n*4600 exceptions,update date to next date.
IF REMAINDER(cnt,exceptionsPerDay) = 0 THEN
dateField := to_timestamp(dateField + 1,'DD/MON/YYYY HH24:MI:SS.FF');
END IF; 

2 个答案:

答案 0 :(得分:0)

从我的角度来看,您的问题是您正在将时间戳与字符串进行比较。

样品表:

SQL> create table test as
  2  select to_timestamp('27.03.2020 04:00:00:000000', 'dd.mm.yyyy hh24:mi:ss:ff6') datum, 'A' name from dual
  3  union all
  4  select to_timestamp('28.03.2020 15:23:00:000000', 'dd.mm.yyyy hh24:mi:ss:ff6') datum, 'A' name from dual;

Table created.

查询应使用时间戳,而不是字符串:

SQL> select *
  2  from test
  3  where datum between to_timestamp('25.03.2020 12:00:00:000000am', 'dd.mm.yyyy hh:mi:ss:ff6am')   --> timestamp
  4                  and to_timestamp('28.03.2020 12:00:00:000000am', 'dd.mm.yyyy hh:mi:ss:ff6am');  --> timestamp

DATUM                                                                       N
--------------------------------------------------------------------------- -
27.03.20 04:00:00,000000000                                                 A

SQL>

您有点“幸运”(尽管由于查询没有失败,但您可能会称其为“ 运气”,但根据返回的行数,它产生了错误的结果)由于数据库升高而出现错误(由于NLS设置不同):

SQL> select *
  2  from test
  3  where datum between '25.03.2020 12:00:00:000000am'     --> string
  4                  and '28.03.2020 12:00:00:000000am';    --> string
where datum between '25.03.2020 12:00:00:000000am'
                    *
ERROR at line 3:
ORA-01830: date format picture ends before converting entire input string


SQL>

字符串的处理方式不同于日期(或时间戳)或数字。也许您会在此示例中清楚看到差异:

SQL> with test (col) as
  2    (select '1'  from dual union all
  3     select '9'  from dual union all
  4     select '20' from dual
  5    )
  6  select *
  7  from test
  8  where col < '9';

CO
--
1
20

SQL>

20 < 9?是的,如果这些是字符串。您可能也遇到了同样的情况。尝试使用正确的数据类型。

答案 1 :(得分:0)

操作时:

dateString :=to_char(dateField,'DD-MON-YYYY HH24:MI:SS.FF');

您正在将dateField的初始值转换为字符串;但似乎尚未设置,因此您最终得到一个空字符串(与null相同)。您从未使用过dateString的原始值。

如果您跳过该操作而只是这样做:

dateString :='26-MAR-20 05.00.00.00000000 AM'; 
dateField := to_timestamp(dateString, 'DD/MON/YYYY HH24:MI:SS.FF') + 0.313 * INTERVAL '1' MINUTE;

然后,您将使用YYYY格式元素转换两位数的20年,这会将其转换为0020年,而不是2020年;但您在格式模型中也没有AM,因此无论如何它将获得ORA-01830,并且使用HH24而不是HH。我认为您的to_char()试图“更正”字符串格式,但这不是一个好方法。

如果您无法控制起始字符串格式,则模型必须与之匹配:

dateString :='26-MAR-20 05.00.00.00000000 AM'; 
dateField := to_timestamp(dateString, 'DD-MON-RR HH:MI:SS.FF AM') + 0.313 * INTERVAL '1' MINUTE;

将dateField的值设置为2020-03-26 05:00:18.780000。

以后您要做的事:

dateField := to_timestamp(dateField + 1,'DD/MON/YYYY HH24:MI:SS.FF');

也在执行dateField + 1的隐式转换-转换为日期,顺便说一下,因为时间戳+数字是日期,而不是时间戳-转换为字符串;它将使用您的NLS_DATE_FORMAT。大概是“ DD-MON-YYYY”之类的东西。

因此逐步完成:

  • dateField +1 =>日期'2020-03-27 05:00:18'(丢失小数秒)
  • 隐式to_char(dateField + 1)=>字符串'2020年3月27日'(丢失时间)
  • to_timestamp(to_char(dateField + 1),'...')=>时间戳'2020-03-27 00:00:00.000000'(时间为午夜)。

因此,您的between最多只能找到2020-03-26 05:00:18.780000和2020-03-27 00:00:00.0000000之间的记录-因此它不会提取任何记录迟于27号午夜。

不需要时不与字符串进行转换;将数据保留为其原始数据类型(在这种情况下为时间戳),并使用带间隔的直接操作。

在两者之间使用无论如何都不是理想的,因为它具有包容性。最好以:

exceptiontime >= timestamp '2020-03-26 05:00:18.780000'
and exceptionTime < timestamp '2020-03-27 05:00:18.780000'
相关问题