2

次の問題は、Fluent NHibernateによってSQL Server 2008 R2に接続された ASP.NET MVC 4 の Web API アプリケーションで実行されています。

したがって、15 の整数と 14 の小数点以下の桁数までの値を保持できる10 進数を格納できるこのフォームがあります。データベース列はdecimal(29,14)、マップされたプロパティと同じように定義されますMap((x) => x.Factor).Column("FACTOR").Precision(29).Scale(14).Not.Nullable()

そのフィールドのデータは、この mask999999999999999.99999999999999に任意の値を保持する必要がありますが、そうではありません。その数により、OverflowExceptionが発生します。これは、リファレンスに記載されている数の制限によるものだと思います: C# and SQL Server

-7.9x1028 to 7.9x1028この表記法(C# リファレンスから) または(SQL Server リファレンスから)は本当にわかりませんが-10^38 +1 to 10^38 -1、エラーはトランザクション コミット アクションにあるため、数値を制限するのは SQL Server の 10 進数だと思います。ViewModel は正しい数値を示しています。

アプリケーションの値を受け入れるには、テーブル列にどの精度/スケールを設定する必要がありますか?

4

1 に答える 1

2

私は本当にこの表記法を理解していません-7.9x1028 to 7.9x1028(C# リファレンスから)

私はDecimal Structure (MSDN)の説明を好みます。

Decimal 値のバイナリ表現は、1 ビットの符号、96 ビットの整数、および 96 ビットの整数を除算し、小数部分を指定するために使用されるスケーリング係数で構成されます。倍率は暗黙的に 10 を 0 ~ 28 の範囲の指数で累乗したものです。したがって、10 進値のバイナリ表現は ((-2 96~ 2 96 ) / 10 (0 ~ 28) )の形式になります。 -(2 96 -1) は MinValue に等しく、2 96 -1 は MaxValue に等しくなります。

10 進数は 9 (29 回繰り返す) / 10 14と書く必要があります。

問題は、9x10 28よりも大きい 9 (29 回繰り返される)が大きすぎて、96 ビット整数表現に変換できないことです (最大値は、最初の定義の 7.9x10 28であり、上記リンクのコメント)

実際、あなたが書き込もうとすると

10 進数 d = 9999999999999999999999999999m;

「定数値計算でオーバーフローしました」というエラーが表示されます。

覚えておくべきことは次のとおり です。これらの有効数字が7.9x10 28を超える整数を形成しない限り、最大29桁の有効数字を使用できます

書き込み時にエラーが出ないようです

decimal d = 999999999999999.99999999999999m ;

ただし、いくつかの丸めが発生します。問題に対してSQLiteデータベースでいくつかのテストを実行すると、パラメーターとして渡された数値が 1000000000000000.0000000000000 (29,13) であり、(29,14) に変換できない場合があります。

(29,14) 列に 1000000000000000.0000000000000 を挿入しようとすると、「数値をデータ型数値に変換する算術オーバーフロー エラー」が発生します。

于 2013-10-22T08:43:09.243 に答える