2
SELECT Asset.AssetID, AnsMaint.Answer, Convert(datetime, AnsMaint.Answer) as maintasdate
FROM Asset INNER JOIN 
AssetAnswer AnsMaint ON AnsMaint.AssetID = Asset.AssetID INNER JOIN  
AssetField FldMaint ON FldMaint.AssetFieldID = AnsMaint.AssetFieldID 
WHERE FldMaint.FieldText = 'Maint. Agreement Term' 
AND ISDATE(AnsMaint.Answer) = 1 
AND Convert(datetime, AnsMaint.Answer) < DateAdd(d, 145, GetDate())

I get the error on the last part of the AND. If I comment the AND out, it works fine. My dates in the DB happen to be 10/10/2012 and are valid. IsDate should weed out anything that is not valid.

In DB the results (when I comment out the last line). I'm completely stumped.

106 10/10/2012  2012-10-10 00:00:00.000
115 10/10/2012  2012-10-10 00:00:00.000

MORE interesting tidbits. If I change the last AND line to

AND DateAdd(d, cast(Asset.MaintenanceFreq as int), Convert(datetime, AnsMaint.Answer)) < DateAdd(d, 45, GetDate()) 

it works. If I take out the 2nd parameter (the cast as int) and replace it with a number or a zero, it gives me the same error.

I'm stumped. Any help would be so much appreciated!

Oh, AssetMaint.Answer is a varchar field in the DB nothing I can do about that.

5
  • I would say from the SQL dialect, this is SQL Server, but the OP could help by clarifying that. Commented Oct 23, 2012 at 16:25
  • "I get the error on the last part of the AND". What's the error message? Commented Oct 23, 2012 at 16:26
  • Yes, this is SQLServer sorry. Commented Oct 23, 2012 at 16:27
  • error message is: Conversion failed when converting datetime from character string. Commented Oct 23, 2012 at 16:28
  • A note about ISDATE() 'weeding out' non-date values - SQL doesn't really do short-circuit logic like imperative languages; the optimizer is allowed to rearrange things as it sees fit. Commented Oct 23, 2012 at 16:35

2 Answers 2

1

From the description, it sounds like the Answer column contains values for some records which can't be converted to a date, and SQL is choosing an execution plan which evaluates the CONVERT before the ISDATE.

Try using a CASE statement for the conversion instead:

WHERE FldMaint.FieldText = 'Maint. Agreement Term' 
AND CASE ISDATE(AnsMaint.Answer) 
   WHEN 1 THEN Convert(datetime, AnsMaint.Answer, 103) 
END < DateAdd(d, 145, GetDate())
Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant! So SQL can "choose" what order to do the execution plan? That is a bit maddening.
0

It's a guess , but I'd say it was mm/dd/yyyy versus dd/mm/yyyy. e.g. 10/10 is okay, but 20/10 or 10/20 might not be.

add the style parameter to the converts e.g.

Convert(datetime, AnsMaint.Answer,103)

You'll have to look up which one based on what ever date format is in your mis-typed field.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.