Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用FoxPro OLEDB驱动程序导入数据时出错_C#_Visual Foxpro - Fatal编程技术网

C# 使用FoxPro OLEDB驱动程序导入数据时出错

C# 使用FoxPro OLEDB驱动程序导入数据时出错,c#,visual-foxpro,C#,Visual Foxpro,我正在使用FoxPro OLE-DB驱动程序将一些数据从FoxPro数据库导入Sql Server数据库。我采用的方法是循环遍历FoxPro表,选择一个DataTable中的所有记录,然后使用SqlBulkCopy将该表插入sqlserver。这可以正常工作,除了少数情况下出现以下错误: System.InvalidOperationException: The provider could not determine the Decimal value. For example, the ro

我正在使用FoxPro OLE-DB驱动程序将一些数据从FoxPro数据库导入Sql Server数据库。我采用的方法是循环遍历FoxPro表,选择一个DataTable中的所有记录,然后使用SqlBulkCopy将该表插入sqlserver。这可以正常工作,除了少数情况下出现以下错误:

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.
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表的数值宽度是固定的。1存储为1.00,而10存储为10.0,小数点后的一位数字是导致问题的原因。现在发现了这个问题,我正在努力解决它。以下函数是我用来将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;
    }
我无法更新FoxPro数据,因为列不允许这样做,如何从DataReader读取记录并修复它?我已经尝试了casting/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列导致了问题

我不知道您是否有权获取Visual Foxpro,但它有一个可以直接上载到SQL Server的升迁向导

它看起来像是微软via的免费试用版


这可能是备忘录/水滴类型的列没有得到正确解释的问题。

您提到了类型转换,但不确定您是如何尝试的。。。在你的试一试中,抓住你所拥有的一切

 row[((DataColumn)cols[i])] = dr[i]; 
您可能希望显式测试columns数据类型并强制它。。。类似于下面DataType.ToString的对象引用不是正数,但您必须在运行/调试期间找到它

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

显然,您也可以从表中列出的结构中测试其他类型…

,这是正确的。在所列表格结构的VFP中,AV_长度为数字类型,长度为4,2分配给十进制位置。因此,它的值最多为9.99。VFP强制数字字段的输入最多为2个十进制位置,1个为小数点,其余为整数部分

其余的基于数字的字段是具有长度的数字字段,但没有小数点位置,这表明它们都是没有小数点位置的整数,因此符合整数数据类型的条件。带小数的数字应为浮点或双列类型


也就是说,我不知道你是如何得到一个10.0的数字4,2的小数点。这是我第一次看到强制将大于所保存结构的分配目的的数字存储在这样的字段中。

我不记得FoxPro出现此问题的原因。我认为这与数字的存储方式有关。不管怎样,解决方案要么是清理数据,要么是重新调整字段大小以允许更大的值。下面的示例代码演示了这个问题

* create a table that can store a value between -0.99 and 99.99 CREATE TABLE "TEST.DBF" (av_length N(4,2)) * insert values between 1.10 and 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) * view the contents of the table * note that records 3 to 10 do not match the field definition BROWSE NORMAL IF MESSAGEBOX("Fix the Data? Select to Change the Field Definition", 0+4+32) = 6 * Solution A: fix the data, and view the table contents again REPLACE ALL av_length WITH MIN(av_length, 9.99) IN "TEST" BROWSE NORMAL ELSE * Solution B: change the field definition, and view the table contents again * note that records 9 & 10 still need to be fixed ALTER TABLE "TEST.DBF" ALTER COLUMN av_length N(12,6) BROWSE NORMAL ENDIF
我安装了FoxPro,可以查看数据-问题是固定宽度的数字字段,例如在FoxPro中,字段定义为宽度4,因此数字0-9显示为小数点后2位0.00、1.00等。9以上的数字显示为1,例如10.0、11.0,正是这些字段导致了问题。我无法从datareader中检索该值以修复它。关键是整个导入过程在.net程序中进行,而无需更改FPdatabase@Macros,听起来很奇怪。您能否使用VFP中的表,对Sample.TXT执行列表结构,然后在此处复制/粘贴该结构,并显示您遇到问题的列定义?对于您遇到的输出,4的宽度听起来非常奇怪。我更新了问题-是AVU长度列导致了问题。我尝试过这样强制转换,以及使用datareaders方法,例如dr.GetString、dr.GetValue和none work!这正是困扰我的地方——我不明白为什么FoxPro会允许这样做,即使我接受这样一个事实,我也无法以一种简单的方式阅读这篇专栏文章datareader@Macros,因为您正在执行到SQL的数据转换,如这里所示,这可能是因为定义的强制过大值使您的数据读取器感到困惑。我会选择av_长度的最大值,看看最大值是多少,然后修改结构以说明最高的合法值,并从中开始。我想知道那也是什么数字。在这个特定的实例中,最大值是10.0,这只是几行。我遇到的问题是,导入是迁移过程的一部分,需要由最终用户执行,因此,即使我修改此数据库实例,也会有数百个其他用户存在潜在的相同问题。尽管您选择重置为最小值可能不是任意确定日期的好选择,但您的alter table 是更好的选择。但是,如果您甚至运行代码,您会发现记录8之前的值实际上已保存。在Foxpro和VFP使用了25年以上之后,我想不起来这是怎么回事了,但我再也没有尝试过通过输入掩码控件来填充字段的容量。