你曾经说过,你有格式MM/DD/YYYY
和MM/DD/YYYY HH:MI:SS AM
,并没有与MM/DD/YYYY HH24:MI:SS
日期。你收到的错误信息表明你错了; '小时数必须在1到12之间'意味着您至少有一行24小时格式的时间。或者,有可能的是,某些事情根本不是一个可以识别的时间。
与存储结构化数据的问题 - 在这种情况下date
- 在自由文本字段为varchar2
,而不是作为一个适当的数据类型,你可以在那里得到任何旧的垃圾,你相信你的应用程序在输入数据时验证数据 - 根据您现在看到的情况,这似乎没有做到。那么,主要问题之一,还有其他问题,包括性能问题。
试图挽救您的数据的唯一方法是编写一个函数,尝试多次转换,并且只有当它有一些有效的选项时才会返回 - 或者用尽了选项。像这样的事情也许:
create or replace function clean_date(text_value varchar2) return date is
begin
begin
return to_date(text_value, 'MM/DD/YYYY HH24:MI:SS');
exception
when others then
null;
end;
begin
return to_date(text_value, 'MM/DD/YYYY HH:MI:SS AM');
exception
when others then
null;
end;
return null;
end clean_date;
/
这只是尝试两种格式,但你可以为你的数据需要添加更多 - 这得到了null
回任何行可能不会受到任何的它试图格式转换。你需要小心你的测试顺序,以避免错误匹配的可能性。每个begin
/exception
/end
子块正在测试一种格式;捕获other
并不理想,但另一种方法是声明所有可能的日期格式异常,这将会很痛苦且容易出错。如果没有异常,则返回该日期值;如果有任何异常,那么它只会移动到下一个块来尝试下一个格式。
这也不会帮助你,如果你有一些非常意想不到的事情,并且不会总是错误,如果你有一个英国格式的日期为DD/MM/YYYY
例如 - 如果日和月都小于13,这是不可能的告诉哪个是哪个。
。不管怎么样,这是你的过滤器将变成:
where trunc(clean_date(a.text_value))
between date '2013-07-14' and date '2013-09-15'
,如果你愿意的话,可以将其转换回字符串,但仍使用一个明智的日期格式比较:
where to_char(clean_date(a.text_value), 'YYYY-MM-DD')
between '2013-07-14' and '2013-09-15'
您的文本字段中的值有多种多样?您是否有混合日期,12小时格式(带AM/PM)的日期和24小时格式的日期?你如何确定所有的日期都是相同的MM/DD/YYYY格式?这就是为什么日期不应该存储在'varchar2'列中,而是总是存储在日期列中的原因。 –
我只有这些格式.. – user1465978
你假设(或希望)你只有这些格式。一个应用程序可以粘贴任何东西在varchar字段 – tbone