文字与字符串列上 Oracle SQL to_date 的格式字符串不匹配
来自 Stack Overflow 的亲爱的 SQL 专家:
环境: Oracle
我试图理解为什么我不能对包含字符串的表列进行 to_date 选择。请注意,下例中具有名称 Value 列的 tableZ 包含一堆字符串,其中一些是正确的格式,例如 6/20/2010 00:00:00。
tableZ
| Value |
| __________________ |
| 6/21/2010 00:00:00 |
| Somestring |
| Some Other strings |
| 6/21/2010 00:00:00 |
| 6/22/2010 00:00:00 |
以下有效
SELECT To_Date(c.Value, 'MM/DD/YYYY HH24:MI:SS') somedate
FROM tableX a, tableY b, tableZ c
WHERE Lower(a.name) = 'somedate'
AND a.id = b.other_id
AND b.id = c.new_id
这将返回类似的内容(这很好):
| somedate |
| __________________ |
| 21.06.2010 00:00:00 |
| 21.06.2010 00:00:00 |
| 22.06.2010 00:00:00 |
以下无效
SELECT To_Date(c.Value, 'MM/DD/YYYY HH24:MI:SS') somedate
FROM properties$aud a, template_properties$aud b, consumable_properties$aud c
WHERE Lower(a.name) = 'somedate'
AND a.id = b.property_id
AND b.id = c.template_property_id
AND To_Date(c.Value, 'MM/DD/YYYY HH24:MI:SS') IS NOT NULL
返回:
ORA-01861: 文字不正确匹配格式字符串
我在这里缺少什么?只是一个快速说明:
...
AND b.id = c.template_property_id
AND To_Date(c.Value, 'DD.MM.YYYY HH24:MI:SS') IS NOT NULL
也不起作用。
谢谢!!
目标能够对 c.value 执行 date BETWEEN 查询,以便选择日期范围。
Dear SQL Gurus from Stack Overflow:
Environment: Oracle
I'm trying to understand why I can't do a to_date selection on a table column that contains strings. Note tableZ with a column of name Value in the example below contains a bunch of strings, some of which are the correct format, for example 6/20/2010 00:00:00.
tableZ
| Value |
| __________________ |
| 6/21/2010 00:00:00 |
| Somestring |
| Some Other strings |
| 6/21/2010 00:00:00 |
| 6/22/2010 00:00:00 |
The following works
SELECT To_Date(c.Value, 'MM/DD/YYYY HH24:MI:SS') somedate
FROM tableX a, tableY b, tableZ c
WHERE Lower(a.name) = 'somedate'
AND a.id = b.other_id
AND b.id = c.new_id
This returns something like (which is good):
| somedate |
| __________________ |
| 21.06.2010 00:00:00 |
| 21.06.2010 00:00:00 |
| 22.06.2010 00:00:00 |
The following does not work
SELECT To_Date(c.Value, 'MM/DD/YYYY HH24:MI:SS') somedate
FROM properties$aud a, template_properties$aud b, consumable_properties$aud c
WHERE Lower(a.name) = 'somedate'
AND a.id = b.property_id
AND b.id = c.template_property_id
AND To_Date(c.Value, 'MM/DD/YYYY HH24:MI:SS') IS NOT NULL
Comes back with:
ORA-01861: literal does not match format string
What am I missing here? Just a quick note:
...
AND b.id = c.template_property_id
AND To_Date(c.Value, 'DD.MM.YYYY HH24:MI:SS') IS NOT NULL
doesn't work either.
Thanks!!
Goal to be able to do date BETWEEN queries on c.value in order to select date ranges.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Oracle 计算在where 子句中找到的条件的顺序不固定。也就是说,它可以选择在其他条件之前评估包含 TO_DATE 的条件,在这种情况下查询将失败。为了防止这种情况,请将ordered_predicates提示添加到您的查询中,但请注意,这可能需要额外的手动调整以提高性能。
显然,从 10g 开始,
ordered_predicates
已被弃用。在这种情况下,我认为您唯一的选择是使用子查询,使优化器被迫首先对其进行评估(即它无法组合查询)。最简单的方法是将 rownum 放入内部查询的 where 语句中。The order that Oracle evaluates the conditions found in the where clause is not fixed. That is to say that it can choose to evaluate the condition containing TO_DATE before the other criteria, in which case the query will fail. To prevent that, add the ordered_predicates hint to your query, but be aware that this may require additional manual tuning to improve performance.
Apparently
ordered_predicates
is deprecated starting with 10g. In that case, I think your only option is to use a sub-query in such a way that optimizer is forced to evaluate it first (i.e. it can't combine the queries). The easiest way to do this is to putrownum
in the where statement of the inner query.另一种技术是将转换嵌入到 CASE 中。
例如
,当子句很复杂时,这会变得非常难看。
Another technique is embed the conversion in a CASE.
For example
This gets REALLY ugly fast when the clauses are complicated though.
测试:
Testing:
您想检查 c.value 是否为有效格式
?这是行不通的,您需要以其他方式执行检查。您可以使用正则表达式(我猜,有一段时间没有使用它们了)。如果您的数据模型允许您识别有问题的行,那就更好了。
Do you want to check if c.value is a valid format with
? This wont work, you will need to perform the check in some other way. You could use a regular expression (i guess, not used them in a while). Better yet if your data model would allow you to discern the rows in question.