Oracle SQL: 日期字段出现 ORA-01858 错误
Oracle SQL: ORA-01858 error on date fields
我有很多 table 名字里有日期。例如 MY_TABLE_2021_06_01, MY_TABLE_2021_06_02, etc
。我正在尝试从 table 名称中提取日期并查看是否有任何 table 超过一年。这是我的代码:
select * from (
select
table_name,
to_date(substr(table_name,-2,2)||'/'||substr(table_name,-5,2)||'/'||substr(table_name,-10,4),'DD/MM/YYYY') TABLE_DATE
from
all_tables
where
owner = 'my_schema'
and table_name like '%_20%'
)
where
TABLE_DATE < trunc(sysdate)-365;
如果我不包含 where 子句 where table_date < trunc(sysdate)-365
,上面的代码可以正常工作。如果我 运行 带有 where 子句的代码,那么我得到
ORA-01858: a non-numeric character was found where a numeric was expected
01858. 00000 - "a non-numeric character was found where a numeric was expected"
*Cause: The input data to be converted using a date format model was
incorrect. The input data did not contain a number where a number was
required by the format model.
*Action: Fix the input data or the date format model to make sure the
elements match in number and type. Then retry the operation.
我尝试了一种不同的、冗长的方法来查看我的代码是否可以工作,但它仍然抛出相同的错误。我的新代码:
select * from (
select table_name, case when table_date < old_date then 1 else 0 end as OLD_TABLE from (
select
table_name,
to_date(substr(table_name,-2,2)||'/'||substr(table_name,-5,2)||'/'||substr(table_name,-10,4),'DD/MM/YYYY') TABLE_DATE,
trunc(sysdate)-365 OLD_DATE
from
all_tables
where
owner = 'my_schema'
and table_name like '%_20%'
)
)
where
old_table = 1
order by
old_table desc;
如果我不包含 where old_table = 1
子句,上面的代码同样可以正常工作,但在包含 where 子句时会出现相同的 ORA-01858 错误。我不明白这一点,因为字段 OLD_TABLE
不是日期字段,但仍然出现日期格式错误。
并非所有满足这些条件的 table:
owner = 'my_schema'
and table_name like '%_20%'
日期格式“有效”,或者与您使用的格式掩码不匹配。
注意:如果table名字是MY_TABLE_2021_06_01
,你为什么TO_DATE(..., 'DD/MM/YYYY')
?
2021_06_01
当然不是 DD/MM/YYYY
格式,而是 YYYY_MM_DD
或 YYYY_DD_MM
(不能说, 06
可以是两个月或天;01
也是如此)。 也许你的代码一旦你修复它就会开始工作。
如果不是,则列出所有名称如 %_20%
的 table 并查看其中哪些违反了您设置的规则。
对我有用的示例:首先示例 tables:
SQL> CREATE TABLE my_table_2021_06_01
2 (
3 id NUMBER
4 );
Table created.
SQL> CREATE TABLE some_other_table_2020_02_17
2 (
3 id NUMBER
4 );
Table created.
提取“名称”超过 1 年的 table 的查询:
SQL> WITH
2 tables
3 AS
4 (SELECT table_name,
5 TO_DATE (REGEXP_SUBSTR (table_name, '\d+_\d+_\d+'),
6 'yyyy_mm_dd') datum
7 FROM all_tables
8 WHERE owner = 'SCOTT'
9 AND table_name LIKE '%20%')
10 SELECT table_name
11 FROM tables
12 WHERE datum <= ADD_MONTHS (TRUNC (SYSDATE), -12);
TABLE_NAME
------------------------------
SOME_OTHER_TABLE_2020_02_17
SQL>
我会使用这个逻辑来提取日期:
select to_date(substr(table_name, -10) default null on conversion error, 'YYYY_MM_DD')
这应该可以用于与 sysdate
的比较。
这既可以处理 table 与格式不匹配的名称,又可以简化日期算法。
我有很多 table 名字里有日期。例如 MY_TABLE_2021_06_01, MY_TABLE_2021_06_02, etc
。我正在尝试从 table 名称中提取日期并查看是否有任何 table 超过一年。这是我的代码:
select * from (
select
table_name,
to_date(substr(table_name,-2,2)||'/'||substr(table_name,-5,2)||'/'||substr(table_name,-10,4),'DD/MM/YYYY') TABLE_DATE
from
all_tables
where
owner = 'my_schema'
and table_name like '%_20%'
)
where
TABLE_DATE < trunc(sysdate)-365;
如果我不包含 where 子句 where table_date < trunc(sysdate)-365
,上面的代码可以正常工作。如果我 运行 带有 where 子句的代码,那么我得到
ORA-01858: a non-numeric character was found where a numeric was expected 01858. 00000 - "a non-numeric character was found where a numeric was expected" *Cause: The input data to be converted using a date format model was incorrect. The input data did not contain a number where a number was required by the format model. *Action: Fix the input data or the date format model to make sure the elements match in number and type. Then retry the operation.
我尝试了一种不同的、冗长的方法来查看我的代码是否可以工作,但它仍然抛出相同的错误。我的新代码:
select * from (
select table_name, case when table_date < old_date then 1 else 0 end as OLD_TABLE from (
select
table_name,
to_date(substr(table_name,-2,2)||'/'||substr(table_name,-5,2)||'/'||substr(table_name,-10,4),'DD/MM/YYYY') TABLE_DATE,
trunc(sysdate)-365 OLD_DATE
from
all_tables
where
owner = 'my_schema'
and table_name like '%_20%'
)
)
where
old_table = 1
order by
old_table desc;
如果我不包含 where old_table = 1
子句,上面的代码同样可以正常工作,但在包含 where 子句时会出现相同的 ORA-01858 错误。我不明白这一点,因为字段 OLD_TABLE
不是日期字段,但仍然出现日期格式错误。
并非所有满足这些条件的 table:
owner = 'my_schema'
and table_name like '%_20%'
日期格式“有效”,或者与您使用的格式掩码不匹配。
注意:如果table名字是MY_TABLE_2021_06_01
,你为什么TO_DATE(..., 'DD/MM/YYYY')
?
2021_06_01
当然不是 DD/MM/YYYY
格式,而是 YYYY_MM_DD
或 YYYY_DD_MM
(不能说, 06
可以是两个月或天;01
也是如此)。 也许你的代码一旦你修复它就会开始工作。
如果不是,则列出所有名称如 %_20%
的 table 并查看其中哪些违反了您设置的规则。
对我有用的示例:首先示例 tables:
SQL> CREATE TABLE my_table_2021_06_01
2 (
3 id NUMBER
4 );
Table created.
SQL> CREATE TABLE some_other_table_2020_02_17
2 (
3 id NUMBER
4 );
Table created.
提取“名称”超过 1 年的 table 的查询:
SQL> WITH
2 tables
3 AS
4 (SELECT table_name,
5 TO_DATE (REGEXP_SUBSTR (table_name, '\d+_\d+_\d+'),
6 'yyyy_mm_dd') datum
7 FROM all_tables
8 WHERE owner = 'SCOTT'
9 AND table_name LIKE '%20%')
10 SELECT table_name
11 FROM tables
12 WHERE datum <= ADD_MONTHS (TRUNC (SYSDATE), -12);
TABLE_NAME
------------------------------
SOME_OTHER_TABLE_2020_02_17
SQL>
我会使用这个逻辑来提取日期:
select to_date(substr(table_name, -10) default null on conversion error, 'YYYY_MM_DD')
这应该可以用于与 sysdate
的比较。
这既可以处理 table 与格式不匹配的名称,又可以简化日期算法。