...di Oracle, Number, ArtitmethicOverflow e anche NH

Vi è mai capitato "Arithmetic operation resulted in an overflow" nella lettura di campi numerici Oracle? Il problema si verifica in fase di lettura di una colonna NUMBER definita senza precisione; tale lettura potrebbe fallire.  La questione è ben descritta in "NHibernate Tales n°2 - Mapping Oracle NUMBER [Decimal]" dove il problema è poi inserito in un contesto in cui NHibernate è l'intermediario verso la base dati. Sebbene l'articolo è molto utile per capire la problematica non mi ha soddisfatto la soluzione poi applicata: l'uso dell'attributo "formula" per eseguire una TRUNC sullo specifico campo. Con tale soluzione si rinuncia alla funzionalità di update del campo. Infatti i campi in cui è si imposta l'attributo "formula" nel mapping sono considerati come campi calcolati e quindi non verranno considerati in fase di update; nella documentazione - parlando di tale attributo - si dice "Computed properties do not have a column mapping of their own" .

Si è cercato di capire il problema alla radice... e se ne è ricavato un custom type (implementando IUserType). Usando NHibernate è nebuloso capire le ragione dell'errore in quanto nascosto tra i mille problemi del mapping. Se NON si usasse NHibernate ecco lo snippet di codice che segue potrebbe generare eccezione.

// Arithmetic operation resulted in an overflow
decimal value = reader.GetDecimal(ordinal);

Il problema si risolve usando esplicitamente le librerie oracle; quindi una buona strategia a provider per l'accesso al dato evita IF e quanto ne consegue.

decimal value =
((Oracle.DataAccess.Client.OracleDataReader)rs).GetOracleDecimal(ordinal);

implementando il custom type ecco una possibile implementazione del metodo NullSafeGet.

public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
    int ordinal = rs.GetOrdinal(names[0]);
    if (rs.IsDBNull(ordinal)) return new Decimal?();
    Oracle.DataAccess.Client.OracleDataReader oracle_dr =
             (Oracle.DataAccess.Client.OracleDataReader)rs;
    Decimal value = oracle_dr.GetOracleDecimal(ordinal);
    return new Decimal?(value);
}

ovviamente va poi inserito il nuovo tipo nella fase di mapping

<property
    name="NomeProprietà"
    column="NOME_COLONNA"
    type="Esempio.OracleNumberType,Esempio"  />

oO0( anche questa volta mi è sfuggita qualche peculiarità di NH? )

 

posted @ giovedì 20 novembre 2008 00:12

Print

Comments on this entry:

# re: ...di Oracle, Number, ArtitmethicOverflow e anche NH

Left by M.rkino at 20/11/2008 01:01
Gravatar
LOL... btw, concordo su osservazione in merito alla precisione. Entrando nel dettaglio del progetto e della soluzione adottata, si tratta di una patch che spero sia temporanea. Nei prossimi giorni tratterò con analisti e DBA in merito alla definizione di una precisione per i campi interessati dal problema :)
Comments have been closed on this topic.
«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011