I am getting some strange behaviour from SQL Server. I have an underlying view that returns an amount field. That amount field is casting from VARCHAR(50) to FLOAT.
I can successfully run the following query:
SELECT AMOUNT
FROM vReturnDetails
I can also successfully run the following query:
SELECT AMOUNT
FROM vReturnDetails v
INNER JOIN MyTable t
ON t.LicenceNumber = v.LicenceNumber
AND t.ReturnYear = v.ReturnYear
WHERE t.ReturnYear = 2012
Similarly I can run this query:
SELECT AMOUNT
FROM vReturnDetails v
INNER JOIN MyTable t
ON t.LicenceNumber = v.LicenceNumber
AND t.ReturnYear = v.ReturnYear
WHERE t.ReturnYear <> 2012
This is where it gets strange though, I cannot run either of the following:
SELECT AMOUNT
FROM vReturnDetails v
INNER JOIN MyTable t
ON t.LicenceNumber = v.LicenceNumber
AND t.ReturnYear = v.ReturnYear
WHERE t.ReturnYear = 2012 OR t.ReturnYear <> 2012
SELECT AMOUNT
FROM vReturnDetails v
INNER JOIN MyTable t
ON t.LicenceNumber = v.LicenceNumber
AND t.ReturnYear = v.ReturnYear
I can successfully run this query though:
SELECT AMOUNT
FROM vReturnDetails v
INNER JOIN MyTable t
ON t.LicenceNumber = v.LicenceNumber
AND t.ReturnYear = v.ReturnYear
WHERE t.ReturnYear <> 2013 --2013 is a dummy value that doesn't exist
Can anyone shed any light on what is happening under the covers here. It makes no sense at all to me so I’m not sure where to start looking to fix the problem.
The error I am receiving is
Error converting data type varchar to float.
This is on Sql Server 2008 SP2
SQL Server is complicated. The order of processing in the SQL engine is not necessarily the same as the order in the query. Filters in WHERE clauses, for instance, can be applied when the data is read, or later after the data is processed.
Clearly, you have some values in the AMOUNT field that are not valid floats. The simplest explanation is that when you ran:
You did not return all the rows . . . and the row with the bad data was later.
Alternatively, vReturnDetails is a view based on underlying data, some of which is bad. When the query is compiled, it might affect where the filtering occurs. In some cases, the engine might decide to read all the data, do the conversion, and then continue — but it gets an error in the conversion disrupting the process.
You can fix this by changing the view to something like:
SQL Server does guarantee the order of evaluation in a case statement. So, this should not return an error.
ISNUMERIC() and CONVERT to FLOAT are not fully consistent. I know ISNUMERIC accepts commas and dollar signs (and maybe other characters). You can also try this (assuming you are using US-style formats for numbers):