1

FoxPro OLE-DB ドライバーを使用して、FoxPro データベースから Sql Server データベースにデータをインポートしています。私が取っているアプローチは、FoxPro テーブルをループし、すべてのレコードを DataTable に選択してから、SqlBulkCopy を使用してそのテーブルを Sql Server に挿入することです。次のエラーが発生するいくつかのインスタンスを除いて、これは正常に機能します。

System.InvalidOperationException: The provider could not determine the Decimal value. For example, the row was just created, the default for the Decimal column was not available, and the consumer had not yet set a new Decimal value.

これを調査し、表示される行をログに記録しました。問題は、FoxPro テーブルの数値の幅が固定されていることです。1 は 1.00 として保存されますが、10 は 10.0 として保存され、問題の原因となっているのは小数点以下 1 桁です。問題を見つけたので、修正に苦労しています。次の関数は、OLEDBReader を DataTable に変換するために使用しているものです。

    private DataTable FPReaderToDataTable(OleDbDataReader dr, string TableName)
    {
        DataTable dt = new DataTable();

        //get datareader schema
        DataTable SchemaTable = dr.GetSchemaTable();
        List<DataColumn> cols = new List<DataColumn>();
        if (SchemaTable != null)
        {
            foreach (DataRow drow in SchemaTable.Rows)
            {
                string columnName = drow["ColumnName"].ToString();
                DataColumn col = new DataColumn(columnName, (Type)(drow["DataType"]));
                col.Unique = (bool)drow["IsUnique"];
                col.AllowDBNull = (bool)drow["AllowDBNull"];
                col.AutoIncrement = (bool)drow["IsAutoIncrement"];
                cols.Add(col);
                dt.Columns.Add(col);
            }
        }

        //populate data
        int RowCount = 1;
        while (dr.Read())
        {
            DataRow row = dt.NewRow();

            for (int i = 0; i < cols.Count; i++)
            {
                try
                {
                    row[((DataColumn)cols[i])] = dr[i];
                }
                catch (Exception ex) {
                    if (i > 0)
                    {
                        LogImportError(TableName, cols[i].ColumnName, RowCount, ex.ToString(), dr[0].ToString());
                    }
                    else
                    {
                        LogImportError(TableName, cols[i].ColumnName, RowCount, ex.ToString(), "");
                    }
                }
            }
            RowCount++;
            dt.Rows.Add(row);
        }
        return dt;
    }

私がしたいのは、小数点以下1桁の問題がある値をチェックすることですが、これらの場合、データリーダーからまったく読み取ることができません。問題のある行で dr.GetString(i) を使用できたはずですが、これにより次のエラーが返されます。

The provider could not determine the String value. For example, the row was just created, the default for the String column was not available, and the consumer had not yet set a new String value.  

列がこれを許可していないため、FoxPro データを更新できません。DataReader からレコードを読み取って修正するにはどうすればよいですか? キャスト/ dr.GetValue / dr.GetDataのすべての組み合わせを試しましたが、すべて同じエラーのバリエーションがあります。

FoxPro テーブルの構造は次のとおりです。

Number of data records:       1664    
Date of last update:          11/15/10
 Code Page:                   1252    
                Field        Field Name                                                            Type                                                                                                   Width                           Dec                   Index   Collate                                            Nulls                               Next                               Step
                    1        AV_KEY                                                                Numeric                                                                                                    6                                                   Asc   Machine                                               No
                    2        AV_TEAM                                                               Numeric                                                                                                    6                                                                                                               No
                    3        AV_DATE                                                               Date                                                                                                       8                                                                                                               No
                    4        AV_CYCLE                                                              Numeric                                                                                                    2                                                                                                               No
                    5        AV_DAY                                                                Numeric                                                                                                    1                                                                                                               No
                    6        AV_START                                                              Character                                                                                                  8                                                                                                               No
                    7        AV_END                                                                Character                                                                                                  8                                                                                                               No
                    8        AV_SERVICE                                                            Numeric                                                                                                    6                                                                                                               No
                    9        AV_SYS                                                                Character                                                                                                  1                                                                                                               No
                   10        AV_LENGTH                                                             Numeric                                                                                                    4                             2                                                                                 No
                   11        AV_CWEEKS                                                             Numeric                                                                                                    2                                                                                                               No
                   12        AV_CSTART                                                             Date                                                                                                       8                                                                                                               No
** Total **                                                                                                                                                                                                  61

問題を引き起こしているのは av_length 列です

4

4 に答える 4

0

FoxProにこの問題がある理由を思い出せません。数字の保存方法と関係があると思います。それにもかかわらず、解決策は、(A)データをクリーンアップするか、(B)フィールドのサイズを変更してより大きな値を許可することです。以下のサンプルコードは、問題を示しています。

* -0.99〜99.99の値を格納できるテーブルを作成します
CREATE TABLE "TEST.DBF"(av_length N(4,2))

* 1.10〜22,222.22222の値を挿入します
INSERT INTO "TEST"(av_length)VALUES(1.1)
INSERT INTO "TEST"(av_length)VALUES(2.2)
INSERT INTO "TEST"(av_length)VALUES(11.11)
INSERT INTO "TEST"(av_length)VALUES(22.22)
INSERT INTO "TEST"(av_length)VALUES(111.111)
INSERT INTO "TEST"(av_length)VALUES(222.222)
INSERT INTO "TEST"(av_length)VALUES(1111.1111)
INSERT INTO "TEST"(av_length)VALUES(2222.2222)
INSERT INTO "TEST"(av_length)VALUES(11111.11111)
INSERT INTO "TEST"(av_length)VALUES(22222.22222)

*テーブルの内容を表示する
*レコード3から10はフィールド定義と一致しないことに注意してください
ノーマルを閲覧

IF MESSAGEBOX( "データを修正しますか?フィールド定義を変更するために選択します"、0 + 4 + 32)= 6
    *解決策A:データを修正し、テーブルの内容を再度表示します
    「テスト」ですべてのav_lengthをMIN(av_length、9.99)に置き換えます
    ノーマルを閲覧
そうしないと
    *解決策B:フィールド定義を変更し、テーブルの内容を再度表示します
    *レコード9と10はまだ修正する必要があることに注意してください
    ALTER TABLE "TEST.DBF" ALTER COLUMN av_length N(12,6)
    ノーマルを閲覧
ENDIF
于 2010-12-01T14:42:04.450 に答える
0

あなたは型キャストについて言及しましたが、どのようにそれを試みたかはわかりません...あなたが持っているあなたのtry/catchで

 row[((DataColumn)cols[i])] = dr[i]; 

列のデータ型を明示的にテストして強制することもできます...(以下のDataType.ToString()のオブジェクト参照は正ではありませんが、実行/デバッグ中にそれを見つける必要があります。

if( cols[i].DataType.ToString().ToLower().Contains( "int" ))
     row[((DataColumn)cols[i])] = (int)dr[i]; 
else
     row[((DataColumn)cols[i])] = dr[i]; 

あなたは明らかに他のタイプもテストすることができます...

于 2010-11-29T14:29:21.207 に答える
0

Visual Foxpro を入手できるかどうかはわかりませんが、SQL Server に直接アップロードできるアップサイジングの「ウィザード」があります。

ダウンロード Visual Foxpro 9、SP2を介して、MS で試用版を無料でダウンロードできるようです。

正しく解釈されていないメモ/ブロブ タイプの列に問題がある可能性があります。

于 2010-11-25T12:44:14.273 に答える
0

リストされたテーブルの構造から、それが何をしているのかは正しいです。リストされているテーブル構造の VFP では、AV_LENGTH は数値型で、長さは 4 で、小数点以下の桁数には 2 が割り当てられます。したがって、ほとんどの場合、値は「9.99」になります。VFP は、数値フィールドの入力を最大 2 桁までに強制します。1 桁は小数点で、残りは整数部分です。

残りの数値ベースのフィールドは長さのある数値ですが、小数点以下の桁数がないことを示します。これは、それらがすべて小数点以下の桁数のない完全な数値であることを示しているため、整数データ型と見なされます。10 進数を含む数値は、float または double の列型に入る必要があります。

そうは言っても、数値の 4、2 の 10 進数で 10.0 の値を取得する方法さえわかりません。これは、実際に保存されている構造体の割り当てられた意図よりも大きな数値をこのようにフィールドに格納することを強制するのを見たのは初めてです。

于 2010-11-30T12:39:49.910 に答える