1

タイプの列に支払いが保存されているテーブルがありますVARCHAR

これは、フィールドからのサンプルデータです。

10.01
55.11

VARCHAR最近、新しいリクエストの一環として、列に格納する数値から小数点を削除する必要がありました。

だから、私はこれを持っていました:

CONVERT(BIGINT, CONVERT(REAL, RTRIM(LTRIM(@amt))) * 100) as PaymentAmount

に変換するにはREAL(からに変換できません)、100を掛けてBIGINTからに変換しますVARCHARBIGINT

現在、問題は、変換中に、最終結果が1セント少なくなる場合があります。

例:'10.11'に変換され1010ます10.151014

これをテストする簡単な方法:

SELECT CONVERT(BIGINT, CONVERT(REAL, RTRIM(LTRIM(10.15))) * 100) as PaymentAmount

クエリの結果はです1014

REALからへの変換を変更し、へのFLOAT変換を削除することで問題を修正しましたBIGINT

別の修正は、次のCASTように使用することです。

CAST(@amt as float)*100  as PaymentAmount

10.00から10.99100の値の範囲の数値で変換を実行しましたが、間違った数値は次のとおりです。

  • 10.11に変換します1010
  • 10.15に変換します1014
  • 10.19に変換します1018
  • 10.23に変換します1022

その範囲の他のすべての値は問題ありません。不思議なことに、11.11うまく変換され1111ます。

だから問題は、なぜ一体それをやっているのか、そしてパターンは何ですか?DataTypeからMSDNREAL は正確な数値ではありませんが、FLOATも正確な数値ですが、floatは全範囲で機能します。

編集:私varcharはサイズが1000であることに言及しませんでした。

4

2 に答える 2

3

あなたが言ったようにREAL、正確な数ではないため、コンバージョンの不一致が発生しています...

REALとの違いが見られる可能性があります。これFLOATは、型ごとに仮数が異なり、精度がさまざまに失われるためです。の使用中に同様の精度の損失をもたらす別の数値を見つけることができると確信していますFLOAT

これらの浮動小数点型の内部動作をさらに理解したい場合は、What Every Computer Scientist Should Know About Floating-Point Arithmeticをご覧ください。

しかし、変換の不一致に加えて、あなたのソリューションには多くの違いがあります...

これらが支払いの場合...なぜVARCHAR小数点なしで金額をフィールドに保存するのですか? これにより、このデータに多くの整合性の問題が発生する可能性が生じます。

次に、データ型は保存するのにより適切なデータ型ではないでしょうMONEY...ご存知のように...お金ですか?

VARCHAR次に、 からに直接変換できないのはなぜBIGINTですか? これは完全に有効な変換です:

DECLARE @amt VARCHAR(50)
SET @amt = ' 1001'
SELECT CONVERT(BIGINT, @amt*100) as PaymentAmount
于 2013-01-29T18:34:26.920 に答える
3
declare @amt varchar(1000)
set @amt = '10.15'

select cast(replace(@amt, '.', '') as bigint)

SQL フィドル

于 2013-01-29T18:34:42.507 に答える