给定的列映射与源或目标中的任何列不匹配。

37

我不知道为什么会出现上述异常,请有经验的人看看……

DataTable DataTable_Time = new DataTable("Star_Schema__Dimension_Time");

DataColumn Sowing_Day = new DataColumn();
Sowing_Day.ColumnName = "Sowing_Day";

DataColumn Sowing_Month= new DataColumn();
Sowing_Month.ColumnName = "Sowing_Month";      

DataColumn Sowing_Year = new DataColumn();
Sowing_Year.ColumnName = "Sowing_Year";

DataColumn Visit_Day= new DataColumn();
Visit_Day.ColumnName = "Visit_Day";

DataColumn Visit_Month = new DataColumn();
Visit_Month.ColumnName = "Visit_Month";

DataColumn Visit_Year = new DataColumn();
Visit_Year.ColumnName = "Visit_Year";

DataColumn Pesticide_spray_day = new DataColumn();
Pesticide_spray_day.ColumnName = "Pesticide_spray_day";

DataColumn Pesticide_spray_Month = new DataColumn();
Pesticide_spray_Month.ColumnName = "Pesticide_spray_Month";

DataColumn Pesticide_spray_Year = new DataColumn();
Pesticide_spray_Year.ColumnName = "Pesticide_spray_Year";

DataTable_Time.Columns.Add(Pesticide_spray_Year);
DataTable_Time.Columns.Add(Sowing_Day);
DataTable_Time.Columns.Add(Sowing_Month);
DataTable_Time.Columns.Add(Sowing_Year);
DataTable_Time.Columns.Add(Visit_Day);
DataTable_Time.Columns.Add(Visit_Month);
DataTable_Time.Columns.Add(Visit_Year);
DataTable_Time.Columns.Add(Pesticide_spray_day);
DataTable_Time.Columns.Add(Pesticide_spray_Month);

adapter.SelectCommand = new SqlCommand(
    "SELECT SowingDate,VisitDate,PesticideSprayDate " +
    "FROM Transformed_Table " + 
    "group by SowingDate,VisitDate,PesticideSprayDate", con);

adapter.SelectCommand.CommandTimeout = 1000;

adapter.Fill(DataSet_DistinctRows, "Star_Schema__Dimension_Time");

DataTable_DistinctRows = DataSet_DistinctRows.Tables["Star_Schema__Dimension_Time"];

int row_number = 0;
int i = 3;

foreach(DataRow row  in DataTable_DistinctRows.Rows)
{
    DataRow flatTableRow = DataTable_Time.NewRow();

    string[] Sarray= Regex.Split(row[0].ToString()," ",RegexOptions.IgnoreCase);
    string[] finalsplit = Regex.Split(Sarray[0], "/", RegexOptions.IgnoreCase);
    string[] Sarray1 = Regex.Split(row[1].ToString(), " ", RegexOptions.IgnoreCase);
    string[] finalsplit2 = Regex.Split(Sarray1[0], "/", RegexOptions.IgnoreCase);
    string[] Sarray2= Regex.Split(row[2].ToString(), " ", RegexOptions.IgnoreCase);
    string[] finalsplit3 = Regex.Split(Sarray2[0], "/", RegexOptions.IgnoreCase);             

    flatTableRow["Sowing_Day"] = int.Parse(finalsplit[0]);
    flatTableRow["Sowing_Month"] = int.Parse(finalsplit[0]);
    flatTableRow["Sowing_Year"] = int.Parse(finalsplit[0]);

    flatTableRow["Visit_Day"] = int.Parse(finalsplit2[0]);
    flatTableRow["Visit_Month"] = int.Parse(finalsplit2[0]);
    flatTableRow["Visit_Year"] = int.Parse(finalsplit2[0]);

    flatTableRow["Pesticide_spray_day"] = int.Parse(finalsplit3[0]);
    flatTableRow["Pesticide_spray_Month"] = int.Parse(finalsplit3[0]);
    flatTableRow["Pesticide_spray_Year"] = int.Parse(finalsplit3[0]);

    DataTable_Time.Rows.Add(flatTableRow);

    i++;
}

con.Open();

using (SqlBulkCopy s = new SqlBulkCopy(con))
{
    s.DestinationTableName = DataTable_Time.TableName;

    foreach (var column in DataTable_Time.Columns)
        s.ColumnMappings.Add(column.ToString(), column.ToString());

    s.BulkCopyTimeout = 500;

    s.WriteToServer(DataTable_Time);
}

我曾经遇到过相同的问题。在我的情况下,类的一个属性在表中没有对应的列,并且它没有被标记为忽略。一旦我添加了该列,错误就消失了。希望这能节省某人的时间。 - Francisco Goldenstein
11
有没有方法可以获取它所抱怨的特定映射关系? - Breandán
12个回答

60

在一些版本的SQL中,比如MSSQL 2005,sqlBulkCopy的列名区分大小写非常重要。

希望这能有所帮助。

1
节省了我很多时间。我正在使用 Sql Server2012,它也是区分大小写的,所以我认为所有版本都是区分大小写的。 - Kazem
1
SQL中的大小写敏感性完全取决于您所针对的数据库使用的排序规则。至于.Net类SqlBulkCopy,它始终区分大小写。 - Shooter McGavin
1
SQL批量复制不提供不匹配的列名!这是一个缺点! - Khalid Bin Sarower

28

一个原因是SqlBulkCopy区分大小写。 按照以下步骤进行:

  1. 通过在C#中使用Contains方法找到源表中的列。
  2. 一旦目标列与源列匹配,获取该列的索引并将其名称提供给SqlBulkCopy

例如:

//Get Column from Source table 
string sourceTableQuery = "Select top 1 * from sourceTable";

// i use sql helper for executing query you can use corde sw
DataTable dtSource 
    = SQLHelper.SqlHelper
        .ExecuteDataset(transaction, CommandType.Text, sourceTableQuery)
        .Tables[0];

for (int i = 0; i < destinationTable.Columns.Count; i++)
{
    string destinationColumnName = destinationTable.Columns[i].ToString();

    // check if destination column exists in source table 
    // Contains method is not case sensitive    
    if (dtSource.Columns.Contains(destinationColumnName))
    {
        //Once column matched get its index
        int sourceColumnIndex = dtSource.Columns.IndexOf(destinationColumnName);

        string sourceColumnName = dtSource.Columns[sourceColumnIndex].ToString();

        // give column name of source table rather then destination table 
        // so that it would avoid case sensitivity
        bulkCopy.ColumnMappings.Add(sourceColumnName, sourceColumnName);
    }                               
}

bulkCopy.WriteToServer(destinationTable);
bulkCopy.Close();

你好,我们有没有办法在 dtSource.Columns 中添加方括号,因为我的数据表中包含它们,例如:[Node]。因此由于这个原因它找不到索引,请给予建议。 - user1046415
不要使用方括号。在数据库中这将是一场噩梦。我建议实现一个查找/替换它们的方法或者事先添加一些验证。 - Jacob H

6
  1. 确保提供ColumnMappings

  2. 确保源列名称的所有值都是有效的并区分大小写。

  3. 确保目标列名称的所有值都是有效的并区分大小写。

  4. 使源不区分大小写


4
你应该标注出处:http://www.sqlbulkcopy-tutorial.net/columnmapping-does-not-match - Mitch Wheat
4
如果不展示如何执行这些步骤,仅列出这些步骤并没有太大的用处。 - Tab Alleman

4

除了上面提到的大小写敏感性之外,请检查您实际上是否拥有相同的列,是否有偶然遗漏了任何一列。我的一个同事就发生了这种情况,他缺少了 87 列中的一列。所以,请仔细检查源文件和目标文件中是否存在每一列。


大小写敏感性肯定是需要检查的东西... - ransems
1
正是我的问题..只因为我在中间缺少了35列中的一列,它就愚蠢地说没有匹配项。我喜欢成为一名开发者。 - Ondrej Valenta

3
在我的情况下,我将一列添加了两次到ColumnMappings中。我删除了重复的部分,一切正常工作。

3

对于其他遇到相同错误的人(但在这种情况下不适用,因为SqlBulkCopy被新建),另一个可能的原因是如果您正在尝试重复使用SqlBulkCopy实例进行多个操作,则列映射将从一个操作保留到另一个操作。在这种情况下,请为需要不同列映射的每个操作实例化一个新的SqlBulkCopy实例。


这对我解决了问题。映射是正确的,但是它记住了旧的映射。实例化一个新的BCP,它就可以工作了。谢谢。 - Mattkwish

3
问题出在 s.ColumnMappings.Add(column.ToString(), column.ToString()); 这一行,是关于目标表和源表的映射。你的 DataTable 中至少有一个列与目标表不匹配。
有很多原因,其中之一可能是数据类型不匹配。如果你尝试将文本插入整数列中,则会出现这种情况。

3

我曾经遇到过同样的错误,原因是我在映射到目标数据库中不存在的列。如果你要进行映射,请确保你的列存在。


1
在我的情况下,连接字符串中的“Initial Catalog=”中数据库名称错误。

1
我遇到了相同的错误。对我来说,我意外地将源数据表中的两个不同列映射到目标数据库表中的同一列。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接