SQL CE e l’Arithmetic Overflow

L’esigenza del cliente consiste in un’aplicazione che, utilizzando SQL CE, permetta la memorizzazione di una serie di informazioni; una di queste è un valore numerico che potra variare da 0 a 99,9 con precisione massima ad un numero dopo la virgola.

Perfetto, creo un DB SQL CE contente la tabella “test” con, fra gli altri, il campo “colonna” di tipo numeric (3,1).

   1: create table test 
   2: (
   3: Id int primary key identity(1,1),
   4: ...
   5: colonna numeric (3,1)
   6: )

Scrivo anche un test che eseguendo il codice:

   1: using (var connection = new SqlCeConnection("Data Source=… "))
   2: {
   3:     connection.Open();
   4:     SqlCeCommand command = connection.CreateCommand();
   5:     command.CommandText = "INSERT INTO Test (Colonna) VALUES (@p0)";
   6:     command.Parameters.Add(new SqlCeParameter("p0", 100));
   7:     command.ExecuteNonQuery();
   8: }

si aspetta un’eccezione.

Perfetto, eseguendo il test l’eccezione viene sollevata ed il test passa.

In realtà l’applicazione non esegue direttamente le istruzioni SQL, ma scrive e legge le informazioni dal DB utilizzando una entity mappata con NHibernate, tale entity espone la property “colonna” di tipo double.

Ovviamente anche questa parte di codice è coperta da alcuni test che ne verifichino il corretto funzionamento.

In particolare scriviamo anche un test che istanziando la entity e valorizzando la property colonna con il valore 100 si aspetta un’eccezione al momento della Insert nel DB.

Ricreo la tabella ed eseguo il test.

Qui esiste nasce il problema: l’eccezione NON viene sollevata!

Ma come? Il campo non era un numeric (3,1)?

A casa mia 100 è maggiore di 99,9!

Come prima azione, dopo aver eseguito il test che inserisce il valore 100 senza aver sollevato l’eccezione, mi collego al db Sql CE con la management studio ed eseguo l’istruzione

   1:  
   2: Select count(*) from test

Risultato = “1”.

Ma allora il record è entrato!

Eseguo l’istruzione

   1: Select Id from test

Risultato = “1”.

Allora eseguo l’istruzione

   1: Select colonna from test

Risultato = “Major Error 0x80004005, Minor Error 0 Arithmetic Overflow”.

Dopo una decina di secondi conditi da una sequenza di “brutti porchi” eseguo l’istruzione

   1: Select cast([COLONNA] as numeric(4,1)) from test

Risultato = “100”.

Colto da un dubbio amletico vado a controllare le proprietà del campo colonna e vedo: “numeric (3,1)

Premesso che ci sono mille soluzioni per aggirare il problema vorrei capire perchè esiste questo comportamento!

Alcune premesse:

La versione del mapping di NHibernate utilizzata è la seguente

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >

la property è semplicemente mappata così:

<property name="Colonna"/>

Il dialetto è quello per Sql CE:

<property name="dialect">NHibernate.Dialect.MsSqlCeDialect</property>

Ora vorrei rispondere alla domanda: “Perchè inserendo il valore 100 con un’istruzione sql ottengo (giustamente) l’eccezione mentre con NHibernate no?”

Scaricando il codice di NHibernate (http://sourceforge.net/projects/nhibernate/ ) e modificando la reference del mio progetto agganciandomi così al codice posso facilmente debuggare quello che avviene al “Save” del mio repository.

Dietro le quinte Nhibernate non fa “magie”, alla fine dei suoi ragionamenti genera una SqlCeConnection ed un SqlCeCommand e ne esegue il metodo ExecuteNonQuery.

L’unica particolarità consiste nel SqlDbType utilizzato da Nhibernate, se la property della mia entity è definita come double Nhibernate forza il SqlDbType del parametro a “Float” e non “Decimal”.

Perfetto: abbiamo risposto alla domanda, ci basta mappare la property così:

<property name="Colonna" type="Decimal" />

ed NHibernate utilizzando il SqlDbType corretto genererà la giusta eccezione.

Ora però mi sorge un’altra domanda: io posso anche accettare che mi si imponga quale SqlDbType utilizzare ma se il campo è numeric (3,1) perchè SQL CE si è memorizzato il valore 100?

A questa domanda non ho ancora saputo rispondere... idee?

Riccardo.

posted @ mercoledì 9 settembre 2009 15.15

Print

Comments on this entry:

# re: SQL CE e l’Arithmetic Overflow

Left by Dissertation Writing at 27/09/2010 16.04
Gravatar
Truly impressive post about "SQL CE e l’Arithmetic Overflow". Custom Dissertation Writing | Dissertation Writing

# re: SQL CE e l’Arithmetic Overflow

Left by pan at 11/11/2010 1.58
Gravatar
Hoodies are very elegant and overcome when used moncler with jeans repressed. His friend and fellows are surely going to be in fear to overcome their dress sense. Its no doubt that some of his friends were going to buy these elegant fabrics. so if you like ,hurry and take action., Moncler 2011 moncler jacken will not let you down.Rapidly changing weather conditions in the world have placed a great responsibility on the manufacturers of clothing and shoes. T So, people are always willing to find clothing that can save them from the effects moncler online shop of severe storm that is either winter or summer. moncler jackets quilted with class A goose down, made with Lampo zippers, Fiocchi buttons and in the most beautiful shiny colours, Moncler jacket never stop the steps of moncler shop pursuit fashion, and make out all kinds of clothes to all people, In such case,moncler jackets men come out this year with special designs.erwwsd

Your comment:



 (will not be displayed)


 
 
 
Please add 4 and 3 and type the answer here:
 

Live Comment Preview:

 
«febbraio»
domlunmarmergiovensab
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910