SqlBulkCopy -给定的ColumnName与源或目标中的任何列都不匹配

本文关键字:目标 任何列 不匹配 ColumnName SqlBulkCopy | 更新日期: 2023-09-27 18:08:58

我试图使用SqlBulkCopy将数据复制到SQL数据库表中,但是它(错误地)说列不匹配。它们确实很相配。如果我使用一个断点来查看被映射的列的名称,那么它们就是正确的。错误消息显示了列的名称,并且它是正确的。

这是我的方法。我有一个与相同的方法,可以工作,唯一的区别是它从哪里获得列名。但是,包含列名的字符串是完全相同的。
    public static bool ManualMapImport(DataTable dataTable, string table)
    {
        if(dataTable != null)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlBulkCopy import = new SqlBulkCopy(connection);
            import.DestinationTableName = "[" + table + "]";
            foreach (string s in Global.SelectedColumns)
            {                    
            /* The s string variable here is the EXACT same as
               the c.ToString() in the other method below */
                if (ColumnExists(table, s))
                    import.ColumnMappings.Add(s, s); 
                else
                    return false;
            }
            connection.Open();
            import.WriteToServer(dataTable); //Error happens on this line
            connection.Close();
            return true;
        }
        else
        {
            return false;
        }
    }

这是几乎相同的工作方法:

    public static bool AutoMapImport(DataTable dataTable, string table)
    {
        if (dataTable != null)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlBulkCopy import = new SqlBulkCopy(connection);
            import.DestinationTableName = "[" + table + "]";           
            foreach (DataColumn c in dataTable.Columns)
            {
                if (ColumnExists(table, c.ToString()))
                    import.ColumnMappings.Add(c.ToString(), c.ToString());
                else
                    return false;
            }
            connection.Open();
            import.WriteToServer(dataTable);
            connection.Close();
            return true;
        }
        else
        {
            return false;
        }
    }

如果有帮助,列名是:ACT_Code, ACT_Paid, ACT_Name, ACT_Terminal_Code, ACT_TCustom1, ACT_TCustom2。这些在数据库本身中是完全相同的。我知道SqlBulkCopy映射是区分大小写的,列名确实是正确的。

这是错误信息:

类型为"System"的未处理异常。InvalidOperationException"发生在System.Data.dll

附加信息:给定的ColumnName 'ACT_Code'不匹配

希望我只是错过了一些明显的东西,但我真的迷路了。

许多谢谢。

编辑:对于任何碰巧和我有同样问题的人,这里是如何我修好了。

而不是让ManualMapImport()方法是接近克隆的AutoMapImport(),我让它循环遍历数据表的列并更改名称,然后将其称为AutoMapImport()Datatable,消除了使用普通字符串at进行映射的需要所有.

SqlBulkCopy -给定的ColumnName与源或目标中的任何列都不匹配

根据MSDN(这里),如果设置了属性,DataColumn.ToString()方法返回"表达式值;否则,ColumnName属性"。

我总是发现ToString()方法是不稳定的(可以根据当前状态/条件改变),所以我建议使用ColumnName属性代替,因为这就是你实际上试图摆脱ToString()


OK,如果失败,那么我不得不猜测这是源数据表中列名称的大小写敏感问题,因为SQLBulkCopy非常大小写敏感,即使SQL DB不是。为了解决这个问题,我想说,当您检查该列是否存在时,您应该返回/使用来自数据表列列表本身的实际字符串,而不是使用传入的任何字符串。这应该能够修复column歧视性例程可能忽略的任何大小写或重音差异。

我有同样的问题…该消息可能看起来有点误导,因为它表明您没有执行正确的映射。

为了找到问题的根源,我决定一步一步地添加表列并调用WriteToServer方法。

假设您有一个有效的列映射,您必须确保源DataTable和目标表之间的以下内容:

  • 列类型和长度(!)匹配
  • 您已经为每个非空(NOT NULL)目标列提供了一个有效值

如果你不控制你的身份列值,并希望SQL Server为你做这项工作,请确保指定SqlBulkCopyOptions.KeepIdentity选项。在本例中,您也不需要将标识列添加到源文件中。

这些应该都是为了您的批量插入工作。