Oracle TO_CHAR(TO_DATE(V_DATE,'d ')in where has ORA-01847 Error

nxowjjhe  于 2023-10-16  发布在  Oracle
关注(0)|答案(2)|浏览(138)

AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '7'
AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '1'
他们有麻烦了。

SELECT TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) AS WEEK
     , OM.* 
FROM ORDER_MASTER OM
WHERE YMD BETWEEN '20230726' AND '20230905'
  AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '7' -- this occur error
  AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '1' -- this occur error too.
ORDER
   BY YMD

此查询发生ORA-01847错误。
AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '7'AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '1'删除,它的工作。
当我检查数据时,ORD_YMD数据正常。
AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '7'AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '1'和没有AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '7'有什么区别?

a14dhokn

a14dhokn1#

关于ORA-01847异常,这意味着您的表中有ymd是无效日期的数据。
查询可以在没有这两个过滤器的情况下工作,因为无效日期不在YMD BETWEEN '20230726' AND '20230905'范围内,因此过滤器排除了无效日期。当您使用TO_DATE包含其他过滤器时,SQL引擎可以选择以任何顺序处理过滤器,并选择在应用BETWEEN过滤器之前对所有行使用TO_DATE,并且由于存在无效日期,因此会生成异常。
你需要修正你的数据,使你的日期是有效的;一旦你这样做了,那么查询就可以工作了。
AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '7'AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '1'和没有AND TO_CHAR(TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd')) <> '7'有什么区别?

  • 注意:您不需要最外面的TO_CHAR。*

拥有它将过滤,以找到天,为您的领土设置,不是一周的第7天或第1天。没有它将包括一周的所有日子。
例如,如果您有示例数据:

CREATE TABLE order_master (ymd) AS
SELECT TO_CHAR(DATE '2023-08-01' + LEVEL, 'YYYYMMDD')
FROM DUAL
CONNECT BY LEVEL <= 7;

然后又道:

SELECT TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') AS WEEK,
       TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'day') AS day,
       OM.* 
FROM   ORDER_MASTER OM
WHERE  YMD BETWEEN '20230726' AND '20230905'
ORDER BY YMD;

输出所有日期:
| 周|天|YMD|
| --|--|--|
| 6 |周三| 20230802 |
| 7 |周四| 20230803 |
| 1 |周五| 20230804 |
| 2 |周六| 20230805 |
| 3 |周日| 20230806 |
| 4 |周一| 20230807 |
| 5 |周二| 20230808 |
但有了过滤器:

ALTER SESSION SET NLS_TERRITORY = 'America';

SELECT TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') AS WEEK,
       TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'day') AS day,
       OM.* 
FROM   ORDER_MASTER OM
WHERE  YMD BETWEEN '20230726' AND '20230905'
AND    TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') <> '7'
AND    TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') <> '1'
ORDER BY YMD;

输出:
| 周|天|YMD|
| --|--|--|
| 4 |周三| 20230802 |
| 5 |周四| 20230803 |
| 6 |周五| 20230804 |
| 2 |周一| 20230807 |
| 3 |周二| 20230808 |
不包括周六和周日。
如果对不同地区运行相同的查询:

ALTER SESSION SET NLS_TERRITORY = 'Germany';

SELECT TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') AS WEEK,
       TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'day') AS day,
       OM.* 
FROM   ORDER_MASTER OM
WHERE  YMD BETWEEN '20230726' AND '20230905'
AND    TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') <> '7'
AND    TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') <> '1'
ORDER BY YMD;

输出:
| 周|天|YMD|
| --|--|--|
| 3 |周三| 20230802 |
| 4 |周四| 20230803 |
| 5 |周五| 20230804 |
| 6 |周六| 20230805 |
| 2 |周二| 20230808 |
不包括星期日和星期一(在欧洲,一周被认为从星期一开始,所以星期一是第1天,星期日是第7天)。
以及:

ALTER SESSION SET NLS_TERRITORY = 'Bangladesh';

SELECT TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') AS WEEK,
       TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'day') AS day,
       OM.* 
FROM   ORDER_MASTER OM
WHERE  YMD BETWEEN '20230726' AND '20230905'
AND    TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') <> '7'
AND    TO_CHAR(TO_DATE(OM.YMD, 'YYYYMMDD'), 'd') <> '1'
ORDER BY YMD;

输出:
| 周|天|YMD|
| --|--|--|
| 6 |周三| 20230802 |
| 2 |周六| 20230805 |
| 3 |周日| 20230806 |
| 4 |周一| 20230807 |
| 5 |周二| 20230808 |
不包括星期四和星期五(在孟加拉国,一周从星期五开始)
fiddle

rsl1atfo

rsl1atfo2#

将日期存储为字符串是一个坏主意。别这样为什么?因为它会导致像你得到的这样的错误:
ORA-01847:日期必须介于1和最后一天之间
这意味着ymd列包含不是有效日期的值,例如。20230855(非任何月份的55号)或20230229(非2023年2月29号)等。
关于你的代码:如果你只关心表示日期值的字符串中的最后两个字符,为什么要进行所有这些转换?使用substr函数代替。
另外,您在select列列表中使用的格式模型建议您要提取 day,而不是 week

SELECT om.*, 
         SUBSTR (ymd, -2) AS day     --> day, not week!
    FROM order_master om
   WHERE     ymd BETWEEN '20230726' AND '20230905'
         AND SUBSTR (ymd, -2) NOT IN ('01', '07')
ORDER BY ymd;

相关问题