在经典报告中使用DatePicker导致ORA-01858错误



在APEX(v22(中,我有一个经典报告(使用模板"cards"(,它具有以下SQL查询:

SELECT TO_CHAR(SUBMIT_DATE, 'yyyy-mm') AS CARD_TITLE,
COUNT(EMP_NUMBER) AS CARD_TEXT
FROM mytable
WHERE TO_DATE(SUBMIT_DATE, 'yy-mm-dd') BETWEEN TO_DATE(:P02_FROM, 'yyyy-mm-dd') AND TO_DATE(:P02_TO, 'yyyy-mm-dd')
GROUP BY TO_CHAR(SUBMIT_DATE, 'yyyy-mm')
ORDER BY TO_CHAR(SUBMIT_DATE, 'yyyy-mm') DESC

在我谈到这个问题之前,让我先解释一下:

  • :P02_FROM和:P02_TO是DatePicker,具有格式掩码"YYYY-MM-DD";此外,每个页面都有一个动态动作,用于提交页面
  • SUBMIT_DATE也在类型为DATE的mytable表中
  • WHERE子句也有更多的条目,因为这个页面中有一个搜索筛选器。由于ORA错误,这在本文中并不那么重要,我不在这里写这篇文章

现在我有以下现象或问题:当我在APEX中按"保存并运行"时,我会看到所有的卡。当我切换到该应用程序中的另一个页面并切换回该页面时,我会收到ORA-01858错误AND:例如,当我刷新此页面上搜索过滤器的设置时,卡片会返回,此ORA错误会消失。为什么?

一方面,我用TO_DATE或TO_CHAR或TRUNC尝试了这个ORA错误,但它没有出现,并且以与上述相同的方式出现。另一方面,我不知道为什么刷新页面会出现这个ORA错误。

这个提交日期还有一个额外的信息:在WHERE子句中,它的格式必须是"dd-mm-yy";如果没有,我会在页面刷新开始时得到ORA错误,这次它不会出现。但另一方面,我需要格式为"yyyy-mm"。

那么,有人能帮我解决这个现象/问题吗?我的错误在哪里?

如果SUBMIT_DATE是一个日期,则不应将其传递给to_date()。这将使用您当前的NLS设置隐式转换为字符串,然后转换回日期-有时这可能会起作用,但更可能出错(正如您所看到的(或获得意外结果。使用2位数年份也不是一个好主意。

所以你可以做:

SELECT TO_CHAR(SUBMIT_DATE, 'yyyy-mm') AS CARD_TITLE,
COUNT(EMP_NUMBER) AS CARD_TEXT
FROM mytable
WHERE SUBMIT_DATE BETWEEN TO_DATE(:P02_FROM, 'yyyy-mm-dd') AND TO_DATE(:P02_TO, 'yyyy-mm-dd')
GROUP BY TO_CHAR(SUBMIT_DATE, 'yyyy-mm')
ORDER BY TO_CHAR(SUBMIT_DATE, 'yyyy-mm') DESC

SELECT TO_CHAR(TRUNCS(SUBMIT_DATE, 'MM'), 'yyyy-mm') AS CARD_TITLE,
COUNT(EMP_NUMBER) AS CARD_TEXT
FROM mytable
WHERE SUBMIT_DATE BETWEEN TO_DATE(:P02_FROM, 'yyyy-mm-dd') AND TO_DATE(:P02_TO, 'yyyy-mm-dd')
GROUP BY TRUNC(SUBMIT_DATE, 'MM')
ORDER BY TRUNC(SUBMIT_DATE, 'MM') DESC

但无论哪种方式,BETWEEN都是包含的,因此它将与SUBMIT_DATE在FROM日期午夜或午夜之后以及直到to日期午夜的行相匹配。

你可能真的想要:

WHERE SUBMIT_DATE >= TO_DATE(:P02_FROM, 'yyyy-mm-dd')
AND SUBMIT_DATE < TO_DATE(:P02_TO, 'yyyy-mm-dd') + 1

其将包括在一天中的任何时间的TO日期的所有数据。(或者,如果您根本不想包含该to日期的数据,请删除+1。(


你可能会想做:

WHERE TRUNC(SUBMIT_DATE, 'DD') BETWEEN ...

这可能就是你试图用to_date()做的——也就是说,将时间部分设置为午夜——如果你明确地转换为字符串,这不会出错:

WHERE TO_DATE(TO_CHAR(SUBMIT_DATE, 'yyyy-mm-dd'), 'yyyy-mm-dd') BETWEEN ...

尽管CCD_ 6更短并且更干净。

虽然这种方法会起作用,并且包括从TO日期起的所有数据,但对该列应用函数会阻止使用该列上的正常索引。通常最好使用>=<过滤器,而不是between,这样就不必修改比较的列值。

在尝试了很多可能性后,我解决了这个问题,我意识到我没有写另外一点:两个DatePicker都有一个不推荐使用的版本和不同的设置,这些设置与其他属性的工作不一致。所以我将其更改为最新的HTML版本,并将所有内容设置为默认设置。在这个变化之后,它工作,也使用亚历克斯普尔的提示。谢谢你的帮助。

最新更新