【问题标题】:I need a workaround for Excel Guessing Data Types problem我需要 Excel 猜测数据类型问题的解决方法
【发布时间】:2010-08-29 14:34:03
【问题描述】:

我正在创建一个实用程序来将数据从 Excel 导入 Oracle 数据库,

我有一个固定的excel文件模板,

现在,当我尝试通过 Jet 提供程序和 ADO.Net - Ole 连接工具导入数据时,我发现以下问题:有些列尚未导入,因为它们的数据类型混合在一起列 [字符串和数字],

我在网上找了这个问题发现原因是guessing data types from Excel

加载代码:

connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0};Extended Properties=Excel 8.0;");
string columns = "P_ID, FULL_NAME_AR, job_no, GENDER, BIRTH_DATE, RELIGION, MARITAL_STATUS, NAT_ID, JOB_Name, FIRST_HIRE_DATE, HIRE_DATE, CONTRACT_TYPE, GRADE_CODE, QUALIFICATION";
string sheetName = "[Emps$]";
OleDbCommand command = new OleDbCommand(string.Format("select {0} from {1} where p_id is not null", columns, sheetName), connection);

connection.Open();
dr = command.ExecuteReader();
DataTable table = new DataTable();
table.Load(dr);

我应该怎么做才能告诉 Excel 停止猜测并将数据作为文本提供给我?

如果没有,您能帮我解决任何问题吗?

提前致谢

【问题讨论】:

  • 如何将记录从excel导入oracle?请问代码?它在哪里失败?
  • 在 Excel 中不能只将整列设置为文本吗?
  • @shahkalpesh:它不会抛出任何异常,它只是忽略文本数据,因为它猜测该列的数据类型是前 8 条记录中的数字,并为非数值返回 null
  • 谢谢。你能发布一些你用来从excel中读取数据的代码吗?
  • 通常的解决方法是创建空的目标表并导入其中,而不是每次运行导入时都创建表。这样您就可以完全控制目标数据类型。

标签: c# ado.net jet import-from-excel


【解决方案1】:

我通过为连接字符串添加 IMEX=1 找到了解决方案,但它有一种特殊的格式,在以下 link 中进行了描述。

IMEX 参数适用于使用混合数字和字母值的列。 Excel 驱动程序通常会扫描前几行 为了确定每列使用什么数据类型。如果一列被确定为数字 基于对前几行的扫描,则此列中包含字母字符的任何行都将 作为 Null 返回。 IMEX 参数(1 为输入模式)强制列的数据类型为 文本以便正确处理字母数字值。

问候

【讨论】:

    【解决方案2】:

    这不完全正确!显然,如果前 8 行为空,则 Jet/ACE 总是假定字符串类型,无论 IMEX=1,如果前 8 行是数字,则始终使用数字类型(同样,无论 IMEX=1)。即使我在注册表中将行读取为 0,我仍然遇到同样的问题。这是让它工作的唯一可靠方法:

    try
    {
        Console.Write(wsReader.GetDouble(j).ToString());
    }
    catch   //Lame unfixable bug
    {
        Console.Write(wsReader.GetString(j));
    }
    

    【讨论】:

    • 这一切都取决于你是否篡改了注册表,尤其是 TypeGuessRows msdn.microsoft.com/en-us/library/bb177610(v=office.12).aspx
    • 尝试使用 wsReader.GetValue(j).ToString(),然后如果你想要它作为双精度,你可以尝试从字符串中解析它。
    • Jim 的问题是,如果您在列中的第一个值是数字,但后来您有像“CDF62738”这样的值,那么这些值将被视为 NULL,因为数字无效:/跨度>
    【解决方案3】:

    你能从 excel 端工作吗?这个在 Excel 中运行的示例会将混合数据类型放入 SQL Server 表中:

    Dim cn As New ADODB.Connection
    
    scn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
    & sFullName _
    & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
    
    cn.Open scn
    
    s = "SELECT Col1, Col2, Col3 INTO [ODBC;Description=TEST;DRIVER=SQL Server;" _
    & "SERVER=Some\Instance;Trusted_Connection=Yes;" _
    & "DATABASE=test].TableZ  FROM [Sheet1$]"
    cn.Execute s
    

    【讨论】:

    • 感谢 Remou,但它不适合我的情况,但我的问题是,为什么我不能在 ADO.Net 中使用 IMEX=1 ?是否有类似的扩展属性适用于 ADO.Net?
    • 为什么不能使用IMEX=1?它只是连接字符串的一部分。在这个pcreview.co.uk/forums/thread-1863969.php,MVP 保罗建议你可以。
    • @Remou:非常感谢,它有效,连接字符串中需要(char)34(来自您添加的链接)。
    • @Homam 请注意,混合必须在注册表项中的 TypeGuessRows 值之前开始:Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/ 除非您要将 TypeGuessRows 设置为 0,这意味着所有行将被扫描。
    【解决方案4】:

    另一种解决方案是在注册表中添加或更改设置 TypeGuessRows。通过将其值设置为 0,将扫描整个文档。

    很遗憾,这些设置可能位于注册表的不同位置,具体取决于您安装的库和版本。

    例如: [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel] "TypeGuessRows"=dword:00000000

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel] "TypeGuessRows"=dword:00000000

    这也将防止超过 255 个字符的文本数据被截断。如果您有一个大于 0 的 TypeGuessRows 数字并且第一个超过 255 个字符的文本出现在该数字之外,就会发生这种情况。

    另见Setting TypeGuessRows for excel ACE Driver

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-03
      • 2014-05-12
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 1970-01-01
      相关资源
      最近更新 更多