-1

Oracleデータベースには、タイプNUMBER(NULL、精度が指定されていない)の列VALUE_NUMBERを持つテーブル(たとえばMYTABLE)があります。このテーブルには値が含まれています1178.2

標準のADO.Net(実際にはODP.Net)を使用してこの列からデータを取得し、10進値を文字列に変換すると、「1178.20」が返されます。明らかに、定数1178.2Mを文字列に変換すると、出力は。になります1178.2

さらに深く掘り下げて、decimal.GetBits()の出力を調べました。これは、両方の数値を比較すると実際には等しいと見なされますが、異なることが判明しました。

以下のコードサンプルは、動作を示しています。

using (var connection = new OracleConnection("my connection string"))
{
    connection.Open();
    var command = connection.CreateCommand();
    command.CommandText = "SELECT VALUE_NUMBER FROM MYTABLE";
    command.CommandType = CommandType.Text;
    using (command)
    {
        var reader = command.ExecuteReader(CommandBehavior.Default);
        reader.Read();
        decimal oracleDecimal = reader.GetDecimal(reader.GetOrdinal("VALUE_NUMBER"));
        Console.WriteLine(oracleDecimal); // output: 1178.20 (NOT expected)
        var bitsFromOracle = decimal.GetBits(oracleDecimal).Select(x => x.ToString());
        var bitsFromOracleString = string.Join(",", bitsFromOracle.ToArray());
        Console.WriteLine(bitsFromOracleString); // 117820,0,0,131072

        // sanity check
        const decimal constantDecimal = 1178.2M;
        Console.WriteLine(constantDecimal); // output: 1178.2 (expected)
        var bitsFromConstant = decimal.GetBits(constantDecimal).Select(x => x.ToString());
        var bitsFromConstantString = string.Join(",", bitsFromConstant.ToArray());
        Console.WriteLine(bitsFromConstantString); // 11782,0,0,65536

        Console.WriteLine(oracleDecimal == constantDecimal); // True 
    }
}

これはどのように説明されるべきですか?

これを機能させるためのテーブルCREATE&INSERTスクリプトは次のとおりです。

CREATE TABLE MYTABLE (
  ID  NUMBER(10)             NOT NULL,
  VALUE_NUMBER           NUMBER
);

INSERT INTO MYTABLE(ID,VALUE_NUMBER) VALUES(1,1178.2);

アップデート:

@Vashによる回答とその後のコメントにより、.Net 10進数タイプには、同等性とは無関係であっても、実際にはその桁数に関する情報が含まれているという正しい結論に至りました。このため、ビット表現が異なりますが、メソッドと1178.2M演算子はこれらの数値を等しいと見なします。1178.20M.Equals()==

4

3 に答える 3

1

あなたが抱えている主な問題は、データベースから受け取る行データにフォーマットを適用しないことです。

特定の形式が必要な場合は、それを指定する必要があります。ドキュメントには、フォーマットタイプがあり、フォーマットの処理方法に関するすべての情報があります。

結果が欲しいだけなら

Console.WriteLine(valueNumber.ToString("N1", CultureInfo.InvariantCulture));
于 2012-08-09T16:35:39.640 に答える
0

これにより、表示の問題や計算の問題が発生していますか?

出力を希望どおりに表示したいだけの場合は、使用できますvalueNumber.ToString("G")か?

于 2012-08-09T16:34:14.057 に答える
-1

できません。必要に応じて、文字列に変換する必要があります。

select 1123.80 num from dual;

select to_char(1123.80, 9999.99) from dual;

つまり、唯一の方法は

SQL> INSERT INTO MYTABLE(ID,VALUE_NUMBER) VALUES(1,1178.20);
SQL> SELECT to_char(VALUE_NUMBER, 9999.99) NUM FROM MYTABLE

NUM
-------------------
1178.20 (string/varchar)

SQL> SELECT VALUE_NUMBER NUM FROM MYTABLE

NUM
-------------------
1178.2 (number)

stringこれにより、値がaになり、再度変換/キャストする必要があるため、後で値に対して数値(10進数)演算を実行するときに問題が発生する可能性がありますnumber。これはあまり推奨されない方法です。NUMBER(10,2)からの精度を無視してもNUMBER(10)、結果は同じになります。

于 2012-08-09T16:21:23.417 に答える