20

DataSet从 Excel 表中填充了一个。我想使用 SQLBulk Copy 在PKLead_Hdr所在的表中插入记录。LeadId

执行以下代码时出现以下错误:

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

string ConStr=ConfigurationManager.ConnectionStrings["ConStr"].ToString();

using (SqlBulkCopy s = new SqlBulkCopy(ConStr,SqlBulkCopyOptions.KeepIdentity))
{
    if (MySql.State==ConnectionState.Closed)
    {
        MySql.Open();
    }

    s.DestinationTableName = "PCRM_Lead_Hdr";
    s.NotifyAfter = 10000;

    #region Comment
    s.ColumnMappings.Clear();

    #region ColumnMapping
    s.ColumnMappings.Add("ClientID", "ClientID");
    s.ColumnMappings.Add("LeadID", "LeadID");
    s.ColumnMappings.Add("Company_Name", "Company_Name");
    s.ColumnMappings.Add("Website", "Website");
    s.ColumnMappings.Add("EmployeeCount", "EmployeeCount");
    s.ColumnMappings.Add("Revenue", "Revenue");
    s.ColumnMappings.Add("Address", "Address");
    s.ColumnMappings.Add("City", "City");

    s.ColumnMappings.Add("State", "State");
    s.ColumnMappings.Add("ZipCode", "ZipCode");
    s.ColumnMappings.Add("CountryId", "CountryId");

    s.ColumnMappings.Add("Phone", "Phone");
    s.ColumnMappings.Add("Fax", "Fax");
    s.ColumnMappings.Add("TimeZone", "TimeZone");
    s.ColumnMappings.Add("SicNo", "SicNo");
    s.ColumnMappings.Add("SicDesc", "SicDesc");

    s.ColumnMappings.Add("SourceID", "SourceID");
    s.ColumnMappings.Add("ResearchAnalysis", "ResearchAnalysis");
    s.ColumnMappings.Add("BasketID", "BasketID");
    s.ColumnMappings.Add("PipeLineStatusId", "PipeLineStatusId");

    s.ColumnMappings.Add("SurveyId", "SurveyId");
    s.ColumnMappings.Add("NextCallDate", "NextCallDate");
    s.ColumnMappings.Add("CurrentRecStatus", "CurrentRecStatus");
    s.ColumnMappings.Add("AssignedUserId", "AssignedUserId");
    s.ColumnMappings.Add("AssignedDate", "AssignedDate");
    s.ColumnMappings.Add("ToValueAmt", "ToValueAmt");
    s.ColumnMappings.Add("Remove", "Remove");
    s.ColumnMappings.Add("Release", "Release");

    s.ColumnMappings.Add("Insert_Date", "Insert_Date");
    s.ColumnMappings.Add("Insert_By", "Insert_By");
    s.ColumnMappings.Add("Updated_Date", "Updated_Date");
    s.ColumnMappings.Add("Updated_By", "Updated_By");

    #endregion
    #endregion

    s.WriteToServer(sourceTable);

    s.Close();

    MySql.Close();
}
4

7 回答 7

40

我在从访问 SQLSERVER 2005 复制数据时遇到了同样的问题,我发现列映射在两个数据源上都是区分大小写的,无论数据库是否敏感。

于 2010-04-09T11:27:10.223 回答
22

嗯,对吗?列名是否存在于两侧?

老实说,我从不关心映射。我喜欢保持简单——我倾向于有一个看起来像服务器上的输入的临时表,然后我SqlBulkCopy进入临时表,最后运行一个存储过程将表从临时表移动到实际表中;好处:

  • 如果导入在任何时候失败,则不会出现实时数据损坏问题
  • 我可以在 SPROC 周围进行交易
  • 我可以在不记录的情况下让 bcp 工作,知道 SPROC 将被记录是安全的
  • 这很简单;-p(不要弄乱映射)

作为最后的想法 - 如果您正在处理批量数据,则可以使用IDataReader(因为这是一个流式 API,而DataTable缓冲 API 也是如此)获得更好的吞吐量。例如,我倾向于使用CsvReader作为 SqlBulkCopy 的源来连接 CSV 导入。或者,我已经编写了 shimsXmlReader以将每个第一级元素呈现为一行IDataReader- 非常快。

于 2009-01-13T10:52:22.827 回答
2

Marc 的答案是我的建议(关于使用临时表)。这可以确保如果您的源不更改,那么您将来导入时会遇到更少的问题。

但是,根据我的经验,您可以检查以下问题:

列名在源和表中匹配 列类型匹配

如果你认为你这样做了,但仍然没有成功。您可以尝试以下方法。

1 - 在表中的所有列中允许空值 2 - 注释掉所有列映射 3 - 重新运行一次添加一列,直到找到问题所在

那应该带出错误

于 2009-01-14T01:56:23.360 回答
2

原因之一是 :SqlBukCOpy 区分大小写。遵循以下步骤:

  1. 在这种情况下,首先您必须使用 C# 中的“包含”方法在源表中找到您的列。
  2. 一旦您的 Destination 列与源列匹配,则获取该列的索引并在 SqlBukCOpy 中给出其列名。

例如:`

//Get Column from Source table 
  string sourceTableQuery = "Select top 1 * from sourceTable";
   DataTable dtSource=SQLHelper.SqlHelper.ExecuteDataset(transaction, CommandType.Text, sourceTableQuery).Tables[0];// i use sql helper for executing query you can use corde sw

 for (int i = 0; i < destinationTable.Columns.Count; i++)
                        {    //check if destination Column Exists in Source table
                            if (dtSource.Columns.Contains(destinationTable.Columns[i].ToString()))//contain method is not case sensitive
                            {
                                int sourceColumnIndex = dtSource.Columns.IndexOf(destinationTable.Columns[i].ToString());//Once column matched get its index
                                bulkCopy.ColumnMappings.Add(dtSource.Columns[sourceColumnIndex].ToString(), dtSource.Columns[sourceColumnIndex].ToString());//give coluns name of source table rather then destination table so that it would avoid case sensitivity
                            }

                        }
                        bulkCopy.WriteToServer(destinationTable);
                        bulkCopy.Close();
于 2016-08-19T11:55:02.660 回答
0

我发现表中的列和输入中的列至少必须匹配。您可以在表中包含更多列,并且输入仍将加载。如果你有更少,你会收到错误。

于 2009-10-26T17:00:04.567 回答
0

想了很久才回答...即使列名大小写相同,如果数据类型不同,您也会得到相同的错误。因此,请检查列名及其数据类型。

PS:临时表是确定的导入方式。

于 2015-08-25T19:45:58.493 回答
0

我会采用分期的想法,但是这是我处理区分大小写性质的方法。很高兴在我的 linq 上受到批评

using (SqlConnection connection = new SqlConnection(conn_str))
{
        connection.Open();
        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
        {
            bulkCopy.DestinationTableName = string.Format("[{0}].[{1}].[{2}]", targetDatabase, targetSchema, targetTable);
            var targetColumsAvailable = GetSchema(conn_str, targetTable).ToArray();
            foreach (var column in dt.Columns)
            {
                if (targetColumsAvailable.Select(x => x.ToUpper()).Contains(column.ToString().ToUpper()))
                {
                    var tc = targetColumsAvailable.Single(x => String.Equals(x, column.ToString(), StringComparison.CurrentCultureIgnoreCase));
                    bulkCopy.ColumnMappings.Add(column.ToString(), tc);
                }
            }

            // Write from the source to the destination.
            bulkCopy.WriteToServer(dt);
            bulkCopy.Close();
        }
}

和辅助方法

private static IEnumerable<string> GetSchema(string connectionString, string tableName)
        {



   using (SqlConnection connection = new SqlConnection(connectionString))
        using (SqlCommand command = connection.CreateCommand())
        {
            command.CommandText = "sp_Columns";
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add("@table_name", SqlDbType.NVarChar, 384).Value = tableName;

            connection.Open();
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    yield return (string)reader["column_name"];
                }
            }
        }
    }
于 2017-10-09T12:41:21.797 回答