0

SQL Server 2008

私は、既存のシステムの変更を設計する任務を負っています。ユーザー インターフェイスでは、ユーザーの通貨タイプから通貨値を入力できるようにする必要があります。変換された金額を USD で保存します。保存された USD で計算を行い、計算結果を USD で保存します。設定された通貨で現在のユーザーに表示します。

主な問題のまとめ ユーザーが値を EUR で入力した場合 (たとえば)、それを USD に変換し、その値をデータベース (db) に、計算に使用された換算レートにリンクされた ID と共に保存します。データベースに保存するときは、表示目的で USD から元に戻すときに EUR で入力された元の金額に正確に戻すために、小数点以下約 8 桁を保存する必要があります。米ドルで金額を表示するように構成されている別のユーザーがログインすると、何が表示されますか? DB にデータを小数点以下 8 桁まで格納している可能性がありますが、丸め/床/天井でセントに切り下げますか? UI とレポートの両方で通貨のセントまでの金額のみを表示すると、特に表示が米ドルである場合や、元の通貨以外の通貨に変換する場合に、ある時点でバランスの問題が発生します。

詳細な説明 値を保存するスケールを考えるのに問題があります。Money データ型を使用しているにもかかわらず、現在は小数点以下 2 桁までしか保存されません。必要に応じて、Money から Decimal(16,9) などに変更します。さらに、現在は UI とレポートでセントまでしか表示されないため、データをユーザーに表示する方法を考えるのに問題があります。

USD からユーザーの通貨タイプに BACK を変換した後、期待値を表示する際に問題が発生することが予想されます。すべては、バックエンドに何を保存するか、どのようにフロア/天井/ラウンドするかにかかっています。

すべての値を基本通貨である USD で保存します。入力された値に対して計算が実行され、その結果から他のデータが作成および保存されます。

このシステムでは、ユーザーが EUR などを設定できるようになり、金額はその通貨と形式でユーザー インターフェイスに表示されます。ユーザーは、その通貨の最低額面よりも小さい値を入力できません。

要約: ユーザーはユーロで金額を入力します。米ドルでのシステム ストア。モジュールは USD 値で実行され、USD 値で他のデータを作成し、結果を保存します。後日、ユーザーはシステムに戻ってレコードを取得し、元の金額を EUR で表示し、その他の計算された金額が EUR に換算されたことを確認できます。当社のレポートとユーザー インターフェースには、セントまでの値しか表示されません。

計算された USD の金額を別の通貨に換算すると、その通貨のセントに四捨五入するだけでなく、表示される値全体でバランスの問題が発生する可能性があります。

In the example below: 'a' is entered by user, 'b' is a look-up in the system, 'c' - 'd' - 'e' are all calculated and stored in database.

     a EUR * b conversion rate = c USD (value floored)
    c USD * <formula> = d result USD (value floored)
    USD - d result USD = e result USD

Balance formula:
USD = e result USD + d result USD

If a user enters 120.00 EUR, we get:
120.00 EUR * 1.330879 = 159.70548000 USD
159.70548000 USD * 0.89 =  142.1378772000 USD
159.70548000 USD - 142.1378772000 USD = 17.5676028000 USD
Balance:
159.70548000 USD  = 17.5676028000 USD + 142.1378772000 USD 

Showing back as EUR:
a: 159.70548000 USD * (1/1.330879 ) = 120 EUR
d: 142.1378772000 USD * (1/1.330879 ) = 106.8000000000000000 EUR
e: 17.5676028000 USD * (1/1.330879 ) = 13.2000000000000000 EUR
Balance:
120 EUR = 13.2000000000000000 EUR + 106.8000000000000000 EUR

If a user enters 120.00 EUR, and we floor our results, we get:
120.00 EUR * 1.330879 = 159.70 USD (value floored)
159.70 USD * 0.89 =  142.13 USD (value floored)
159.70 USD - 142.13 USD = 17.57 USD
Balance:
159.70 USD  = 17.57 USD + 142.13 USD 

Showing back as EUR:
a: 159.70 USD * (1/1.330879 ) = 119.99588242 EUR
d: 142.13 USD * (1/1.330879 ) = 106.79408120 EUR
e: 17.57 USD * (1/1.330879 ) = 13.20180122 EUR
Balance:
119.99588242 EUR = 13.20180122 EUR + 106.79408120 EUR
If we had floored the currency conversion: 119.99 EUR = 13.20 EUR + 106.79 EUR
Should be showing 120.00 EUR since that was what was originally entered by the user.

Showing back as EUR (and rounding):
a: 159.70 USD * (1/1.330879 ) = 120.00 EUR (Rounded)
d: 142.13 USD * (1/1.330879 ) = 106.79 EUR (Rounded)
e: 17.57 USD * (1/1.330879 ) = 13.20 EUR (Rounded)
Balance:
120.00 EUR <> 13.20 EUR + 106.79 EUR (actually equals 199.99)
Off by 1 cent.
4

1 に答える 1

0

これでうまくいくと思います:

ユーザーが値を入力できる UI のすべての場所で、次のものが必要になります。 1. 通貨タイプのセントまで DB に格納された ReportedValue。2. 基本通貨タイプのセントまで格納される BaseValue。3. 元の通貨の種類、通貨の乗数、目的の通貨の種類、および変換の有効日を含む行の PK である CurrencyConversionKey。

これら 3 つの値があれば、UI でいつでもユーザーに表示できる、元の入力金額です。または、別のユーザー (構成された通貨の種類が異なる) が UI でレコードを取得した場合は、元の入力金額を別の通貨の種類に変換します。現在行っているようにすべての内部計算を引き続き行うことができます (これは BaseValue になります)。これにより、すべての計算がセント単位に抑えられ、ビジネス ロジックの丸めの問題が自動的に処理されます。

于 2013-09-26T12:37:02.487 に答える