When you try to insert the rows from a DataTable and the data in one of the columns of one of the rows is too big to fit into the destination column in the database, you get a SqlException with the error message: "Received an invalid column length from the bcp client for colid N." (Where "N" is a number.) It doesn't tell you which row, and it's a pain to figure out what column to look at.
Exception: "Received invalid column length from bcp client for colid N".
Cause: Data is not in the proper format (for example, column length exceed the length of the column in the database).
This exception gives the column number and that is not easy to find when the Excel sheet contains a large number of columns. So we are using the following code to find the column name.
- protected string GetBulkCopyColumnException(Exception ex, SqlBulkCopy bulkcopy)
-
- {
- string message = string.Empty;
- if (ex.Message.Contains("Received an invalid column length from the bcp client for colid"))
-
- {
- string pattern = @"\d+";
- Match match = Regex.Match(ex.Message.ToString(), pattern);
- var index = Convert.ToInt32(match.Value) - 1;
-
- FieldInfo fi = typeof(SqlBulkCopy).GetField("_sortedColumnMappings", BindingFlags.NonPublic | BindingFlags.Instance);
- var sortedColumns = fi.GetValue(bulkcopy);
- var items = (Object[])sortedColumns.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sortedColumns);
-
- FieldInfo itemdata = items[index].GetType().GetField("_metadata", BindingFlags.NonPublic | BindingFlags.Instance);
- var metadata = itemdata.GetValue(items[index]);
- var column = metadata.GetType().GetField("column", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
- var length = metadata.GetType().GetField("length", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
- message = (String.Format("Column: {0} contains data with a length greater than: {1}", column, length));
- }
- return message;
- }
The preceding method returns a message with a column name and length. We will use this method when using sqlbulkcopy with a catch block as below:
- SqlConnection conn = new SqlConnection(Connection_Enc.Decrypt_Connect());
-
- try {
- conn.Open();
-
- using (SqlBulkCopy sbc = new SqlBulkCopy(conn)) {
- sbc.DestinationTableName = "CallCenter_ZoneWiseTemp";
- sbc.WriteToServer(dtLocalData);
- sbc.Close();
- }
- }
- catch (Exception ex) {
- string errorMessage =string.Empty;
-
- if (ex.Message.Contains("Received an invalid column length from the bcp client for colid"))
- {
-
- errorMessage = base.GetBulkCopyColumnException(ex, sbc);
-
- Exception exInvlidColumn = new Exception(errorMessage,ex);
- base.LogDataAccessException(exInvlidColumn, System.Reflection.MethodBase.GetCurrentMethod().Name);
- }