2012-05-04 8 views
44

के लिए BCP क्लाइंट से एक अमान्य स्तंभ लंबाई प्राप्त मैं सी # कोड से SQL सर्वर 2005 के लिए बल्क अपलोड csv फ़ाइल डेटा चाहते हैं, लेकिन मैं नीचे त्रुटि का सामना कर रहा हूँ -colid 6

से अमान्य स्तंभ लंबाई प्राप्त के लिए BCP ग्राहक colid 6.

जब डेटाबेस सर्वर

उत्तर

47

एक्सेल (स्तंभ क्रमांक 6) में डेटा स्तंभों में से एक में एक या अधिक सेल डेटा को DataColumn डेटाप्रकार लंबाई से अधिक है करने के लिए थोक प्रतिलिपि लिखने डेटाबेस।

एक्सेल में डेटा सत्यापित करें। डेटाबेस तालिका स्कीमा के अनुपालन में अपने प्रारूप के लिए एक्सेल में डेटा को भी सत्यापित करें।

इससे बचने के लिए, डेटाबेस तालिका में स्ट्रिंग डेटाटाइप की डेटा-लंबाई को पार करने का प्रयास करें।

उम्मीद है कि इससे मदद मिलती है।

98

मुझे पता है कि यह पोस्ट पुराना है लेकिन मैं इस मुद्दे पर भाग गया और अंततः यह निर्धारित करने के लिए एक समाधान निकाला कि कौन सा कॉलम समस्या पैदा कर रहा था और इसकी आवश्यकता के रूप में इसे वापस रिपोर्ट करें। अंततः मुझे पता चला कि कोलिड जो एसक्लएक्सप्शन में वापस लौटाया गया है शून्य आधारित नहीं है, इसलिए आपको मूल्य प्राप्त करने के लिए 1 से घटाकर उसे घटा देना होगा। इसके बाद इसे SqlBulkCopy उदाहरण के _sortedColumnMappings ArrayList की अनुक्रमणिका के रूप में उपयोग किया जाता है, जो कॉलम मैपिंग की अनुक्रमणिका नहीं है जो SqlBulkCopy उदाहरण में जोड़ा गया था। ध्यान देने योग्य एक बात यह है कि SqlBulkCopy प्राप्त पहली त्रुटि पर रुक जाएगा, इसलिए यह एकमात्र मुद्दा नहीं हो सकता है लेकिन कम से कम इसे समझने में मदद करता है।

try 
{ 
    bulkCopy.WriteToServer(importTable); 
    sqlTran.Commit(); 
}  
catch (SqlException ex) 
{ 
    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); 
     throw new DataFormatException(String.Format("Column: {0} contains data with a length greater than: {1}", column, length)); 
    } 

    throw; 
}
+2

यह बहुत अच्छी तरह से काम करता है, के लिए धन्यवाद भेजने। – Steven

+0

क्या आपको पता है कि पंक्ति एनआर भी प्राप्त करना संभव है? –

+0

आप डेटाफॉर्मेट एक्सेप्शन कहां से प्राप्त कर रहे हैं? क्या यह आपकी परियोजना के लिए एक स्थानीय वर्ग है? इसके अलावा आपका कोड अन्य सभी एसक्यूएल अपवादों को खाता है ... शायद एक रेथ्रो करें? – OmegaMan

0

मैं जबकि SQL BulkCopy विकल्प का उपयोग कर डेटाबेस तालिका के लिए एक स्ट्रिंग गुजर मुद्दे का एक समान तरह सामना करना पड़ा। जिस स्ट्रिंग को मैं पास कर रहा था वह 3 वर्णों का था जबकि गंतव्य कॉलम की लंबाई varchar(20) थी। मैंने स्ट्रिंग में किसी भी स्थान (अग्रणी और पिछला) के कारण यह जांचने के लिए Trim() फ़ंक्शन का उपयोग करके डीबी में डालने से पहले स्ट्रिंग को ट्रिम करने का प्रयास किया था। स्ट्रिंग को ट्रिम करने के बाद, यह ठीक काम करता था।

आप text.Trim()

0

कोड के महान टुकड़ा साझा करने के लिए धन्यवाद कोशिश कर सकते हैं,!

मैं वास्तविक डेटामेम्बरनाम को एक त्रुटि पर क्लाइंट को वापस फेंकने के लिए प्रतिबिंब का उपयोग करके समाप्त हुआ (मैं डब्लूसीएफ सेवा में थोक बचत का उपयोग कर रहा हूं)। उम्मीद है कि किसी और को यह पता चलेगा कि मैंने इसे कैसे उपयोगी बनाया।

static string GetDataMemberName(string colName, object t) { 
 
    foreach(PropertyInfo propertyInfo in t.GetType().GetProperties()) { 
 
    if (propertyInfo.CanRead) { 
 
     if (propertyInfo.Name == colName) { 
 
     var attributes = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), false).FirstOrDefault() as DataMemberAttribute; 
 
     if (attributes != null && !string.IsNullOrEmpty(attributes.Name)) 
 
      return attributes.Name; 
 
     return colName; 
 
     } 
 
    } 
 
    } 
 
    return colName; 
 
}

0

तालिका में कॉलम आप थोक डालने/कॉपी कर रहे हैं के आकार की जाँच करें। वर्चर या अन्य स्ट्रिंग कॉलम को विस्तारित करने की आवश्यकता हो सकती है या आपके द्वारा डालने वाले मान को ट्रिम करने की आवश्यकता है। कॉलम ऑर्डर तालिका में भी होना चाहिए।

जैसे, varchar स्तंभ 30 से 50 का आकार बढ़ाएं =>

ALTER तालिका [dbo]। [TableName] ALTER स्तंभ [columnName] VARCHAR (50)