ORA-01839 "date not valid for month specified" for to_date 在 where 子句中
ORA-01839 "date not valid for month specified" for to_date in where clause
我有以下查询 (BOCRTNTIME - varchar e.g 2015-02-28 12:21:45, VIEW_BASE_MARIX_T - some view
):
select BOCRTNTIME
from VIEW_BASE_MARIX_T
where to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD')
between (to_date ('2016-01-01', 'YYYY-MM-DD'))
and (to_date ('2016-02-01', 'YYYY-MM-DD'))
执行时出现错误:
ORA-01839: "date not valid for month specified"
我认为BOCRTNTIME
中可能有不正确的数据,所以执行以下查询:
select distinct
substr(BOCRTNTIME,1,8),
substr(BOCRTNTIME,9,2)
from VIEW_BASE_MARIX_T
order by substr(BOCRTNTIME,9,2);
但一切看起来都很好:http://pastebin.com/fNjP4UAu。
此外,以下查询执行时没有任何错误:
select to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD')
from VIEW_BASE_MARIX_T;
我已经尝试将 trunc()
添加到所有 to_date()
但没有成功。我还创建了 pl/sql 程序,该程序采用一项一项的形式 VIEW_BASE_MARIX_T
并将其转换为日期 - 一切正常。
知道为什么我在第一次查询时出错吗?
UPD:在视图中使用的 table 上的查询工作正常,但在视图中 - 不是
UPD2:我们几乎没有相同产品的环境,但只有一个出现错误
UPD3:问题已通过在视图
中使用的 table 中搜索无效日期解决
这可能不太可能,但 between 的语法中没有括号,您尝试过删除它们吗?
select
BOCRTNTIME
from VIEW_BASE_MARIX_T
where
to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD') between to_date ('2016-01-01', 'YYYY-MM-DD') and to_date ('2016-02-01', 'YYYY-MM-DD')
评论有点太长 - 创建一个简单的函数来测试日期:
CREATE FUNCTION is_Valid_Date(
in_string VARCHAR2,
in_format VARCHAR2 DEFAULT 'YYYY-MM-DD'
) RETURN NUMBER DETERMINISTIC
AS
dt DATE;
BEGIN
dt := TO_DATE( in_string, in_format );
RETURN 1;
EXCEPTION
WHEN OTHERS THEN
RETURN 0;
END;
/
那么你可以这样做:
SELECT BOCRTNTIME
FROM VIEW_BASE_MARIX_T
WHERE is_Valid_Date( substr(BOCRTNTIME,1,10) ) = 0;
您可能会发现 4 月、6 月、9 月或 11 月有该月 31 日的条目,或者 2 月的值大于 28/29(尽管我在您粘贴的数据中看不到类似的内容) .
否则您可以尝试使用 ANSI 日期文字:
SELECT BOCRTNTIME
FROM VIEW_BASE_MARIX_T
WHERE to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD') between DATE '2016-01-01' and DATE '2016-02-01';
或者,更简单,给定输入格式:
SELECT BOCRTNTIME
FROM VIEW_BASE_MARIX_T
WHERE substr(BOCRTNTIME,1,10) between '2016-01-01' and '2016-02-01';
我认为可能发生的情况是 Oracle 正在将谓词推送到视图的基础表。
您是否尝试过运行查询
select to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD') BOCRTNTIME
from MY_TABLE
而不是查询视图?
您也可以使用 NO_PUSH_PRED 提示
来确认这一点
select /*+ NO_PUSH_PRED(VIEW_BASE_MARIX_T) */
BOCRTNTIME
from VIEW_BASE_MARIX_T
where
to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD') between (to_date ('2016-01-01', 'YYYY-MM-DD')) and (to_date ('2016-02-01', 'YYYY-MM-DD'))
错误消息说您所在月份的日期无效。用这个检查你的数据:
-- Check for months with 30 days
select substr(BOCRTNTIME,9,2), substr(BOCRTNTIME,6,2) from VIEW_BASE_MARIX_T where to_number(substr(BOCRTNTIME,6,2)) in (4,6,9,11) and to_number(substr(BOCRTNTIME,9,2))>30;
-- Check for february
select substr(BOCRTNTIME,9,2), substr(BOCRTNTIME,6,2) from VIEW_BASE_MARIX_T where to_number(substr(BOCRTNTIME,6,2))=2 and to_number(substr(BOCRTNTIME,9,2))>28;
我有以下查询 (BOCRTNTIME - varchar e.g 2015-02-28 12:21:45, VIEW_BASE_MARIX_T - some view
):
select BOCRTNTIME
from VIEW_BASE_MARIX_T
where to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD')
between (to_date ('2016-01-01', 'YYYY-MM-DD'))
and (to_date ('2016-02-01', 'YYYY-MM-DD'))
执行时出现错误:
ORA-01839: "date not valid for month specified"
我认为BOCRTNTIME
中可能有不正确的数据,所以执行以下查询:
select distinct
substr(BOCRTNTIME,1,8),
substr(BOCRTNTIME,9,2)
from VIEW_BASE_MARIX_T
order by substr(BOCRTNTIME,9,2);
但一切看起来都很好:http://pastebin.com/fNjP4UAu。 此外,以下查询执行时没有任何错误:
select to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD')
from VIEW_BASE_MARIX_T;
我已经尝试将 trunc()
添加到所有 to_date()
但没有成功。我还创建了 pl/sql 程序,该程序采用一项一项的形式 VIEW_BASE_MARIX_T
并将其转换为日期 - 一切正常。
知道为什么我在第一次查询时出错吗?
UPD:在视图中使用的 table 上的查询工作正常,但在视图中 - 不是
UPD2:我们几乎没有相同产品的环境,但只有一个出现错误
UPD3:问题已通过在视图
中使用的 table 中搜索无效日期解决这可能不太可能,但 between 的语法中没有括号,您尝试过删除它们吗?
select
BOCRTNTIME
from VIEW_BASE_MARIX_T
where
to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD') between to_date ('2016-01-01', 'YYYY-MM-DD') and to_date ('2016-02-01', 'YYYY-MM-DD')
评论有点太长 - 创建一个简单的函数来测试日期:
CREATE FUNCTION is_Valid_Date(
in_string VARCHAR2,
in_format VARCHAR2 DEFAULT 'YYYY-MM-DD'
) RETURN NUMBER DETERMINISTIC
AS
dt DATE;
BEGIN
dt := TO_DATE( in_string, in_format );
RETURN 1;
EXCEPTION
WHEN OTHERS THEN
RETURN 0;
END;
/
那么你可以这样做:
SELECT BOCRTNTIME
FROM VIEW_BASE_MARIX_T
WHERE is_Valid_Date( substr(BOCRTNTIME,1,10) ) = 0;
您可能会发现 4 月、6 月、9 月或 11 月有该月 31 日的条目,或者 2 月的值大于 28/29(尽管我在您粘贴的数据中看不到类似的内容) .
否则您可以尝试使用 ANSI 日期文字:
SELECT BOCRTNTIME
FROM VIEW_BASE_MARIX_T
WHERE to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD') between DATE '2016-01-01' and DATE '2016-02-01';
或者,更简单,给定输入格式:
SELECT BOCRTNTIME
FROM VIEW_BASE_MARIX_T
WHERE substr(BOCRTNTIME,1,10) between '2016-01-01' and '2016-02-01';
我认为可能发生的情况是 Oracle 正在将谓词推送到视图的基础表。
您是否尝试过运行查询
select to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD') BOCRTNTIME
from MY_TABLE
而不是查询视图?
您也可以使用 NO_PUSH_PRED 提示
来确认这一点select /*+ NO_PUSH_PRED(VIEW_BASE_MARIX_T) */
BOCRTNTIME
from VIEW_BASE_MARIX_T
where
to_date(substr(BOCRTNTIME,1,10),'YYYY-MM-DD') between (to_date ('2016-01-01', 'YYYY-MM-DD')) and (to_date ('2016-02-01', 'YYYY-MM-DD'))
错误消息说您所在月份的日期无效。用这个检查你的数据:
-- Check for months with 30 days
select substr(BOCRTNTIME,9,2), substr(BOCRTNTIME,6,2) from VIEW_BASE_MARIX_T where to_number(substr(BOCRTNTIME,6,2)) in (4,6,9,11) and to_number(substr(BOCRTNTIME,9,2))>30;
-- Check for february
select substr(BOCRTNTIME,9,2), substr(BOCRTNTIME,6,2) from VIEW_BASE_MARIX_T where to_number(substr(BOCRTNTIME,6,2))=2 and to_number(substr(BOCRTNTIME,9,2))>28;