A: 

Do you want to check if c.value is a valid format with

AND To_Date(c.Value, 'DD.MM.YYYY HH24:MI:SS') IS NOT NULL

? 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.

bert
No, my goal as stated above is to do BETWEEN queries so that I can select date ranges. The IS NOT NULL is just a simple way for me to check if the query works at all, and the oracle error suggests otherwise.
Rio
+6  A: 

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.

SELECT /*+ ordered_predicates */
               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

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 put rownum in the where statement of the inner query.

SELECT To_Date(c.Value, 'MM/DD/YYYY HH24:MI:SS') somedate 
  FROM (SELECT value 
          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 rownum > 0) 
 WHERE To_Date(c.Value, 'MM/DD/YYYY HH24:MI:SS') IS NOT NULL
Allan
A neat idea but I didn't get it to work with initial testing?
Rio
@Rio, if you want more help, saying "I didn't get it to work" is not good enough.
Jeffrey Kemp
His comment was in response to just the ordered_predicate section. The rest was added when I researched why it wasn't working...
Allan
Thank you Allan. This answer is valuable and hopefully will enlighten others as well!
Rio
As I understand it, the Oracle optimizer will sometimes push predicates into the in-line view, resulting in to_date and to_number firing on invalid values, even when the in-line view should filter them out. This is unfortunate, in cases like this example. See http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:11504677087008 and http://www.dbdebunk.com/page/page/1351381.htm
Shannon Severance
@Shannon Severance, that is correct. However, you can prevent oracle from pushing the predicate to the in-line view by adding a value to that view that would be changed if the predicate is changed. That's the purpose of including rownum in the inner query.
Allan
@Allan: Thanks for explaining that.
Shannon Severance
+1  A: 
create or replace function to_date_or_null(v_str_date in varchar2
        , v_str_fmt in varchar2 default null) return date as
begin
    if v_str_fmt is null then
        return to_date(v_str_date);
    else
        return to_date(v_str_date, v_str_fmt);
    end if;
exception
    when others then
        return null;
end to_date_or_null;
/

Testing:

SQL> select to_date_or_null('2000-01-01', 'YYYY-MM-DD') from dual -- Valid;

TO_DATE_OR_NULL('20
-------------------
2000-01-01 00:00:00

SQL> select to_date_or_null('Not a date at all') from dual -- Not Valid;

TO_DATE_OR_NULL('NO
-------------------


SQL> select to_date_or_null('2000-01-01') from dual -- Valid matches my NLS settings;

TO_DATE_OR_NULL('20
-------------------
2000-01-01 00:00:00

SQL> select to_date_or_null('01-Jan-00') from dual -- Does not match my NLS settings;

TO_DATE_OR_NULL('01
-------------------
Shannon Severance
A: 

Another technique is embed the conversion in a CASE. For example

SELECT * FROM table
WHERE col_a = '1'
AND case when col_a = '1' then to_date(col_b,'DD/MM/YYYY') end = trunc(sysdate)

This gets REALLY ugly fast when the clauses are complicated though.

Gary