これはばかげた質問のように聞こえますが、eコマース関連のプロジェクトの多くのテーブルデザインでは、通貨にdecimal(19、4)が使用されていることがほとんどです。
なぜスケール4なのか?なぜ2ではないのですか?
多分私は将来の潜在的な計算の問題を見逃しているのでしょうか?
まず、他の回答から誤ったアドバイスを受けています。以下に従ってください(64ビットアーキテクチャ上の64ビットOS)。
declare @op1 decimal(18,2) = 0.01
,@op2 decimal(18,2) = 0.01;
select result = @op1 * @op2;
result
---------.---------.---------.---------
0.0001
(1 row(s) affected)
タイトルの下にあるアンダースコアの数に注意してください-全部で39です。 (カウントを助けるために、10分の1をピリオドに変更しました。)これは、38桁(最大許容値、および64ビットCPUのデフォルト)に加えて、表示上の小数点に十分です。両方のオペランドはdecimal(18,2)として宣言されていますが、計算はdecimal(38,4) データ・タイプ。 (私は64ビットマシンでSQL 2012を実行しています。一部の詳細はマシンのアーキテクチャとOSによって異なる場合があります。)
したがって、精度が失われていないことは明らかです。逆に、オーバーフローのみが発生し、精度の低下は発生しません。これは、整数演算として実行される10進数オペランドのすべての計算の直接的な結果です。 decimal型の中間フィールドのタイプがintであると報告されると、インテリセンスでこのアーティファクトが時々表示されます。
上記の例を考えてみましょう。 2つのオペランドは両方ともタイプdecimal(18,2)であり、スケールが2の値1の整数として格納されます。乗算すると、積は依然として1ですが、スケールは、スケールを追加して評価され、整数値1とスケール4の結果を作成します。これは、0.0001の値で、タイプdecimal(18,4)の値が格納されます。値1、スケール4の整数として。
最後の段落をもう一度読んでください。
すすぎ、もう一度繰り返します。
実際には、64ビットマシンとOSでは、余分なビットが空いているCPUで計算が行われているため、これは実際には* decimal(38,4)型として格納および繰り越されます。
あなたの質問に戻ります-世界のすべての主要通貨(私が知っている)は小数点以下2桁しか必要ありませんが、4が必要な場合は少数であり、通貨取引や債券販売など、小数点以下4桁の金融取引があります。場所は法律で義務付けられています。 moneyデータ型を考案する場合、Microsoftは、必要な通常のスケールではなく、必要となる可能性のある最大スケールを選択したようです。トランザクションや企業が実際に19桁を超える精度を必要とすることがどれほど少ないかを考えると、これは非常に賢明なようです。
あなたが持っている場合:
その場合は、スケール2でタイプdecimalを使用しても安全です(decimal(19,2)またはdecimal(18,2)またはdecimal(38,2))お金の代わりに。これにより、一部の変換が容易になり、上記の前提条件があれば、費用はかかりません。これらの仮定areを満たす典型的なケースは、GLまたはトランザクションをペニーに追跡する補助元帳会計システムにあります。ただし、株式または債券取引システムは- 満たされないこれらの仮定では、4桁のスケールが法律で義務付けられています。
2つのケースを区別する方法は、トランザクションがcentsまたはpercentsのどちらで報告されるかであり、2桁のスケールしか必要としないか、または4桁のスケールが必要な基本ポイント.
プログラミングの状況にどのケースが当てはまるかまったくわからない場合は、アプリケーションの法的要件およびGAAP要件について、コントローラーまたは財務責任者に相談してください。 (S)彼はあなたに決定的なアドバイスを与えることができます。
ガソリン価格のようなものは、余分な「スケール」ポジションを使用します。ガロンあたり$ 1.959のガスを見たことがあるでしょう?
10進数を使用する場合、ビジネス要件に応じてどのように使用するかはあなた次第です。
ただし、SQLでMoneyデータ型をデフォルトで使用する場合、小数点以下4桁で格納されます。
SQLでは、19は整数、4は小数です。
10進数が2つしかなく、いくつかの計算の結果を格納して、小数点以下が2つを超える場合、これらの追加の小数点を格納する「方法」はありません。
一部の通貨は、小数点以下2桁で動作します。
Moneyではなく、decimalデータ型を使用してください。