views:

286

answers:

1

We're using SQL Server Standard Edition 8.00.760 (SP3) on a Small Business Server 2003 platform. While tracking down an inexplainable System.Data.DBConcurrencyException for a Strongly Typed DataSet, I discovered the following problem:

Given is this table:

CREATE TABLE [dbo].[Auszahlung](
    [auszahlungid] [int] IDENTITY(1,1) NOT NULL,
    [spesenkonto] [decimal](10, 2) NOT NULL,

And this query for a row originally inserted with decimals calculated in .NET 2.0 using a Strongly Typed DataSet:

SELECT [auszahlungid], [spesenkonto]
FROM [Auszahlung] 
WHERE [auszahlungid] = 35

When run on a Sql Server Management Studio 2005 client, I get this result:

auszahlungid spesenkonto
------------ ---------------------------------------
35           0.00

(1 Zeile(n) betroffen)

But when run on the Query Analyzer on the Sql Server 2000, I get this negative zero:

auszahlungid spesenkonto  
------------ ------------ 
35           -.00

(1 row(s) affected)

Consequently, the queries

SELECT [auszahlungid], [spesenkonto] 
FROM [Auszahlung] 
WHERE [auszahlungid] = 35
AND [spesenkonto] = 0.00

and (inconsequently on the SQL 2000 Query Analyzer)

SELECT [auszahlungid], [spesenkonto]
FROM [Auszahlung] 
WHERE [auszahlungid] = 35
and spesenkonto = -.00

both yield 0 rows, and any row update using a .NET Strongly Typed DataSet will raise a System.Data.DBConcurrencyException because of the the optimistic concurrency restriction.

Questions:

Is this a known bug in MSSQL?

How can I make our system reliable again without sacrificing optimistic concurrency?

A: 

Perhaps, when working with SQL2000 driver interprets numeric as float... Can you try the following workaround

SELECT [auszahlungid], [spesenkonto] 
FROM [Auszahlung] 
WHERE [auszahlungid] = 35
AND ABS([spesenkonto]) < 0.01
Bogdan_Ch
Of course 'AND ABS([spesenkonto]) < 0.01' works, but I won't manually "correct" the code generated by VisualStudio 2005 in the Strongly Typed DataSet for handling optimistic concurrency. This is the core of the problem: The code generated by the framework seems (in rare edge cases) to produce data that can't be handled by that very code.
tarnold
For optimistic concurrency we usually have only one field that is usually have the same name ModificationDate and that is assigned to DateTime.Now in .NET for all updated records. We modify conditions for concurrency to be WHERE [primary_key] = @original_key AND ModificationDate = @original_ModificationDate and exclude all other fields from concurrency conditions. I don't like the ideas to have autogenerated quesries with 20 or 30 fields in WHERE condition.
Bogdan_Ch