SqlBulkCopy无效

我有一个从Excel表填充的DataSet 。 我想在LeadId为PK的Lead_Hdr表中使用SQLBulk Copy来插入记录。

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

给定的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(); } 

好吧,是吗? 列名是否存在于双方?

说实话,我从不打扰过映射。 我喜欢保持简单 – 我倾向于有一个看起来像服务器输入的登台表,然后我将SqlBulkCopy放入登台表,最后运行一个存储过程将表从登台表移动到实际表中; 好处:

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

最后的想法 – 如果您正在处理批量数据,您可以使用IDataReader获得更好的吞吐量(因为这是一个流API,其中 – DataTable是一个缓冲的API)。 例如,我倾向于使用CsvReader作为SqlBulkCopy的源来挂起CSV导入。 或者,我在XmlReader周围编写了一些XmlReader ,将每个第一级元素作为IDataReader的一行显示 – 非常快。

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

Marc的回答是我的推荐(使用临时表)。 这可确保如果您的来源未发生变化,将来导入的问题将会减少。

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

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

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

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

这应该可以解决这个问题

其中一个原因是:SqlBukCOpy区分大小写。 按照步骤:

  1. 在该案例中,您首先必须在C#中使用“Contain”方法在源表中找到您的列。
  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(); 

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

很长一段时间都在回答……即使列名称大小相同,如果数据类型不同,也会得到相同的错误。 因此,请检查列名称及其数据类型。

PS:临时表是导入的最终方式。

我会选择升级的想法,但这是我处理区分大小写的方法。 很高兴在我的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 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"]; } } } }