ORA-01843:没有有效的月份错误

时间:2015-08-28 08:06:26

标签: sql oracle date date-comparison

我在Oracle DB中有一个varchar2数据类型的列。此列中存储的典型值类似于06/16/2015 02:14:18 AM。 我想在2015年8月1日之后获得本专栏有记录的所有记录。

select * 
from MYTABLE 
where to_date(substr(MYCOLUMN,1,10),'dd-mm-yyyy') > to_date('01-08-2015','dd-mm-yyyy');

但是,我得到了ORA-01843。我在哪里做错了?

3 个答案:

答案 0 :(得分:3)

尊重VARCHAR中的格式

....where to_date(substr(MYCOLUMN,1,10),'mm/dd/yyyy')

答案 1 :(得分:1)

  

我在Oracle DB中有一个varchar2数据类型的列。存储在此列中的典型值类似于06/16/2015 02:14:18 AM。

第一个问题是为什么将 DATE 存储为字符串?使用适当的数据类型数据库设计效果中最重要的部分之一。

了解 DATE 没有您看到的格式,它内部存储在7 bytes中,这是Oracle的专有格式。不建议将日期存储为字符串以具有固定格式。

我建议首先修复设计,以便在比较日期时不必执行此开销活动。从长远来看,它会对你有所帮助。

<强> 1。添加新列作为DATE数据类型。

ALTER TABLE table_name 
   ADD new_column DATE;

<强> 2。更新新列。

UPDATE table_name 
   SET new_column = TO_DATE(old_column, 'mm/dd/yyyy hh:mi:ss pm');

第3。删除旧列。

ALTER TABLE table_name 
   DROP COLUMN old_column;

<强> 4。将新列重命名为旧列名称。

ALTER TABLE table_name
  RENAME COLUMN old_name to new_name;

现在,您可以轻松比较日期:

SELECT * FROM MYTABLE WHERE mycolumn > to_date('01-08-2015','dd-mm-yyyy');

这也将使用日期列上的任何常规索引

从效果的角度来看

如果您现在不修复它,您将继续面临性能问题。由于SUBSTR的即时修复不允许您使用任何常规索引,因此您需要创建基于函数的索引

答案 2 :(得分:0)

如果您的表格中包含06/16/2015 02:14:18 AM等所有值,那么您可以对trunc(to_date(MYCOLUMN,'mm/dd/yyyy HH:mi:SS PM'),'dd')使用to_date(substr(MYCOLUMN,1,10),'dd-mm-yyyy')