0

「同様の」スキーマを使用して、さまざまなデータベース タイプ (SQL Server、Oracle、DB2) に接続する必要があるアプリケーションに取り組んでいます。テーブル名、列などは同じであるという点で「類似した」スキーマと言いますが、基になるデータ型はそのデータベース型に固有です。たとえば、SQL Server と Oracle データベースの両方に、'tablename' という名前のテーブルと 'column' という名前の列があります。'column' のデータ型は、Oracle では NUMBER、SQL Server では float です。

適切なプロバイダー ファクトリを取得し、接続し、一般的な ADO インターフェイスを介してクエリを実行することには問題ありませんが、この列にアクセスする方法についてはよくわからず、問題を抱えています。

Oracle の場合、NUMBER データ型フィールドにアクセサ関数 'GetDecimal()' を使用することになっていると思いますが、実際には、GetInt32()、GetDouble() などの他のアクセサを使用すると、キャスト例外が発生するようです。SQL Server では、アクセサ関数 'GetDouble()' を使用することになっています。基になるデータベースのデータ型に関係なく、単一のアクセサー関数でこの値を取得する方法/戦略はありますか? バックエンド データベース スキーマを制御できないことに注意してください。

ありがとう、私は応答に感謝します。

4

2 に答える 2

0

IDataReader.GetValue を使用できますが、どこかでキャストする必要があります。アクセスを汎用ラッパーに抽象化し、データ リーダーで GetSchemaTable を使用して、GetValue の結果を何にキャストするかについて情報に基づいた決定を下すことができます。

于 2012-07-31T03:56:25.443 に答える
0

はい、できます。両方の型 (SqlServer の float と Oracel の数値) を decimal などの .NET データ型にキャストできることを考慮すると、System.Convertクラスのメソッドに依存できます。実際に行う必要があります:

internal static decimal Read(IDbCommand cmd)
{
    cmd.CommandText = @"SELECT column FROM tablename LIMIT 1";
    using (var r = cmd.ExecuteReader())
    {
        while(r.Read())
        {
            return Convert.ToDecimal(r[0]);
            //instead of return r.GetDecimal(0);

            //or even better return r[0].ToFormattedDecimal();
        }
    }
}

public static decimal ToFormattedDecimal(this object d)
{
    if (d is DBNull || d == null) //important line - to check DbNull
        return 0; //your value

    try
    {
        return Convert.ToDecimal(d).Normalize();
    }
    catch (Exception ex)
    {
        throw ex;
        // or may be return 0;
    }
}

public static decimal Normalize(this decimal d)
{
    return d / 1.00000000000000000000000000000m;
}

あなたの仕事をより簡単にするための拡張メソッドを書きました。このNormalize関数は、23.0000 などの 10 進数値の末尾にある不要なゼロをすべて削除します。

于 2012-11-10T10:19:53.867 に答える