【问题标题】:SqlBulkCopy failing with String conversion issueSqlBulkCopy 因字符串转换问题而失败
【发布时间】:2009-12-11 18:48:11
【问题描述】:

我有一个视图,它生成了许多列,我想将这些列批量加载到另一个具有相同名称列的表中。

当我循环遍历 SqlDataReader 并每次使用 SqlCommand 使用 SqlParameters 进行插入时,此过程运行良好。显然,对于许多 100000 行来说,这太慢了。

我改用 SqlBulkCopy,因为视图列名和目标数据库表的列名和类型匹配(因为上述过程有效!),这似乎可行。

但是,在第一条记录上,它失败并出现 InvalidOperationException,提示“String 类型的给定值无法转换为指定目标列的 smalldatetime 类型”。第一行只有一个日期列,其值为 NULL。

视图只返回列的子集,但不是所有列的都可以为空。

任何帮助将不胜感激。

【问题讨论】:

    标签: .net sql sqlbulkcopy


    【解决方案1】:

    sqlbulkcopy 不会自动映射同名的列。它假定您的选择将按照在目标表中看到的相同顺序返回列。

    因此,如果目标表中有 7 列并且视图返回 5,它将尝试将这 5 列放在目标表的前 5 列中。

    SqlBulkCopy 类可以采用列映射的集合。这应该可以解决问题

    【讨论】:

      【解决方案2】:

      你为什么不只使用一条 sql 语句

      INSERT INTO YourTable (Col1, Col2,...) SELECT Col1, Col2, .. FROM YourView
      

      如果视图和表有相同的列,你可以在YourTable后面去掉(Col1, Col2,...),把语句改成

      INSERT INTO YourTable SELECT Col1, Col2, .. FROM YourView
      

      但一般来说,指定要插入的列是一种很好的形式。

      您还可以将 where 子句应用于 YourView 中的选择。

      【讨论】:

      • 不幸的是,它们位于两个单独的数据库中,并且如上所述使用 SqlCommands 运行单独的插入语句很慢。
      • 我已经撤消了负分,因为我意识到这在单个数据库配置中是一个很好的解决方案。我猜它不能跨越多个连接?
      • 不过,这应该没问题,您可以使用 4 部分表示法。 SELECT * FROM Server.Database.dbo.Table
      • 如何在应用程序中使用凭据?如果我将连接对象传递给 SqlCommand,我看不出它是如何工作的,因为它们可能会在两个不同的域中运行以进行身份​​验证。
      • 你是否设置了链接服务器,那么你可以使用这个。
      【解决方案3】:

      尝试将SET DATEFORMAT 设置为正确的连接格式(ymd、dmy、mdy、...),然后重试。如果您的日期是本地化格式而不是与语言环境无关的格式,则通常会发生此错误。

      至于在一次插入中完成所有操作,不建议这样做,因为这被认为是长时间运行的事务,而不是批量插入操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-31
        • 2019-11-17
        相关资源
        最近更新 更多