无法正确检索具有格式化日期值的记录,需要选择具有正确日期格式的查询以获取每天插入的所有记录
我的脚本中有一个这样的日期字符串-
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;
答案 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”之类的东西。
因此逐步完成:
因此,您的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'