Groups | Blog | Home
all groups > sql server programming > june 2004 >

sql server programming : Is this a Convert & Group By Bug?


IanT
6/17/2004 11:26:01 PM
Is this a Bug?

In SQL server 2000 service pack 3a,
I am having problems with the convert function which is causing reports to be unreliable even after testing.

The only difference between Part 1 and Part 2 is a primary key but part 2 gives a convert error.

Furthermore,
Adding about 20 rows more to Part 1 creates a convert error.

Furthermore,
Removing any rows from Part 2 hides the convert error.

---------------------------------
-- PART 1
---------------------------------
--
-- No key, Nothing in A to join
-- => No convert error.
--
CREATE TABLE #A ( A varchar (15))
CREATE TABLE #B ( B varchar (15) NOT NULL)
INSERT INTO #B VALUES ( 'a' )
INSERT INTO #B VALUES ( 'a' )
INSERT INTO #B VALUES ( 'a' )
INSERT INTO #B VALUES ( 'a' )
GO
SELECT A, SUM(CONVERT(MONEY, B))
FROM #A JOIN #B ON A = B
GROUP BY A
GO
DROP TABLE #A
DROP TABLE #B
GO


--------------------------------
-- Part 2
--------------------------------
--
-- Primary key #A, Nothing in A to join
-- => Convert error.
--
CREATE TABLE #A ( A varchar (15), CONSTRAINT [WPK] PRIMARY KEY ( A ))
CREATE TABLE #B ( B varchar (15) NOT NULL)
INSERT INTO #B VALUES ( 'a' )
INSERT INTO #B VALUES ( 'a' )
INSERT INTO #B VALUES ( 'a' )
INSERT INTO #B VALUES ( 'a' )
GO
SELECT A, SUM(CONVERT(MONEY, B))
FROM #A JOIN #B ON A = B
GROUP BY A
GO
DROP TABLE #A
DROP TABLE #B
GO
David Portas
6/18/2004 8:36:49 AM
The reason for this is clear if you look at the execution plans. The index
causes the aggregate on Table B to be calculated before the join which means
the invalid rows raise an exception. Since the conversion error is generated
at runtime rather than compile time and since both plans are valid I think
this falls into the category of unusual behaviour rather than a serious bug.

It's not difficult to generate this type of problem when a calculated
expression is materialized before a join operation but to require the join
always to be applied first would limit the effectiveness of some query
optimizations. This behaviour is really your friend!

The solution is to fix whatever data quality issue is causing the error or
otherwise to exclude the failing rows from the query. For example:

SELECT A, SUM(CONVERT(MONEY, B))
FROM #A JOIN #B ON A = B AND ISNUMERIC(B)=1
GROUP BY A

--
David Portas
SQL Server MVP
--

Steve Kass
6/18/2004 2:55:04 PM
In addition to David's suggestion, a solution is to eliminate the bad
conversion using CASE:

.... CONVERT(MONEY, CASE WHEN ISNUMERIC(B) THEN B ELSE '0' END) ...

This should work assuming no B values that convert to some numeric type but
not to MONEY.

Steve Kass
Drew University

[quoted text, click to view]

IanT
6/29/2004 6:02:01 PM
Thank you, this has help me avoid the problem.

Some reports like payslip summarys per person require data and comments from many areas (job, leave, tax and bank data). To solve this problem we compile the data into a table of text fields for direct printing. In this case, we want to create subtotal entries.

[quoted text, click to view]
IanT
6/29/2004 7:06:02 PM
Thanks you.
I will ask the other programmers to use it.

I like this solution because I know now that I can not lower the priority of the convert expression against the join and I am not going to check the query plan of every programmer's stored procedure.


[quoted text, click to view]
AddThis Social Bookmark Button